macro-assembler-ia32.h revision b0fe1620dcb4135ac3ab2d66ff93072373911299
1b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Copyright 2010 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifndef V8_IA32_MACRO_ASSEMBLER_IA32_H_
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define V8_IA32_MACRO_ASSEMBLER_IA32_H_
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#include "assembler.h"
32756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick#include "type-info.h"
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen// Flags used for the AllocateInNewSpace functions.
3825f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsenenum AllocationFlags {
3925f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // No special flags.
4025f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  NO_ALLOCATION_FLAGS = 0,
4125f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // Return the pointer to the allocated already tagged as a heap object.
4225f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  TAG_OBJECT = 1 << 0,
4325f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // The content of the result register already contains the allocation top in
4425f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  // new space.
4525f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  RESULT_CONTAINS_TOP = 1 << 1
4625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen};
4725f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen
48e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// Convenience for platform-independent signatures.  We do not normally
49e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke// distinguish memory operands from other operands on ia32.
50e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarketypedef Operand MemOperand;
51e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
52a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Forward declaration.
53a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass JumpTarget;
54b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass PostCallGenerator;
55a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// MacroAssembler implements a collection of frequently used macros.
57a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass MacroAssembler: public Assembler {
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
59a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MacroAssembler(void* buffer, int size);
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // GC Support
63a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
647f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // For page containing |object| mark region covering |addr| dirty.
657f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // RecordWriteHelper only works if the object is not in new
666ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // space.
676ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void RecordWriteHelper(Register object,
686ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         Register addr,
696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                         Register scratch);
706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Check if object is in new space.
726ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // scratch can be object itself, but it will be clobbered.
73b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  template <typename LabelType>
746ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void InNewSpace(Register object,
756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                  Register scratch,
766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                  Condition cc,  // equal for new space, not_equal otherwise.
77b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                  LabelType* branch);
786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
798defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // For page containing |object| mark region covering [object+offset]
808defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // dirty. |object| is the object being stored into, |value| is the
818defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // object being stored. If offset is zero, then the scratch register
828defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // contains the array index into the elements array represented as a
838defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // Smi. All registers are clobbered by the operation. RecordWrite
848defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // filters out smis so it does not update the write barrier if the
858defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // value is a smi.
86a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void RecordWrite(Register object,
87a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                   int offset,
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                   Register value,
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                   Register scratch);
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
918defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // For page containing |object| mark region covering |address|
928defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // dirty. |object| is the object being stored into, |value| is the
938defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // object being stored. All registers are clobbered by the
948defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // operation. RecordWrite filters out smis so it does not update the
958defd9ff6930b4e24729971a61cf7469daf119beSteve Block  // write barrier if the value is a smi.
968defd9ff6930b4e24729971a61cf7469daf119beSteve Block  void RecordWrite(Register object,
978defd9ff6930b4e24729971a61cf7469daf119beSteve Block                   Register address,
988defd9ff6930b4e24729971a61cf7469daf119beSteve Block                   Register value);
998defd9ff6930b4e24729971a61cf7469daf119beSteve Block
100a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef ENABLE_DEBUGGER_SUPPORT
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
102a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Debugger Support
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
104402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void DebugBreak();
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Activation frames
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void EnterInternalFrame() { EnterFrame(StackFrame::INTERNAL); }
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LeaveInternalFrame() { LeaveFrame(StackFrame::INTERNAL); }
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); }
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); }
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
116b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Enter specific kind of exit frame. Expects the number of
117b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // arguments in register eax and sets up the number of arguments in
118b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // register edi and the pointer to the first argument in register
119b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // esi.
120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void EnterExitFrame(bool save_doubles);
121d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
1228a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  void EnterApiExitFrame(int argc);
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Leave the current exit frame. Expects the return value in
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // register eax:edx (untouched) and the pointer to the first
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // argument in register esi.
127b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void LeaveExitFrame(bool save_doubles);
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Leave the current exit frame. Expects the return value in
1308a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // register eax (untouched).
1318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  void LeaveApiExitFrame();
1328a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
133d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Find the function context up the context chain.
134d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void LoadContext(Register dst, int context_chain_length);
135a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
13680d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Load the global function with the given index.
13780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void LoadGlobalFunction(int index, Register function);
13880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
13980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Load the initial map from the global function. The registers
14080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // function and map can be the same.
14180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void LoadGlobalFunctionInitialMap(Register function, Register map);
14280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
143b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Push and pop the registers that can hold pointers.
144b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PushSafepointRegisters() { pushad(); }
145b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void PopSafepointRegisters() { popad(); }
146b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  static int SafepointRegisterStackIndex(int reg_code);
147b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
148a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
149a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // JavaScript invokes
150a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
151a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Invoke the JavaScript function code by either calling or jumping.
152a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokeCode(const Operand& code,
153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& expected,
154a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& actual,
155b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                  InvokeFlag flag,
156b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                  PostCallGenerator* post_call_generator = NULL);
157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokeCode(Handle<Code> code,
159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& expected,
160a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  const ParameterCount& actual,
161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  RelocInfo::Mode rmode,
162b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                  InvokeFlag flag,
163b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                  PostCallGenerator* post_call_generator = NULL);
164a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Invoke the JavaScript function in the given register. Changes the
166a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // current context to the context in the function before invoking.
167a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokeFunction(Register function,
168a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      const ParameterCount& actual,
169b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                      InvokeFlag flag,
170b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                      PostCallGenerator* post_call_generator = NULL);
171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
172402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void InvokeFunction(JSFunction* function,
173402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                      const ParameterCount& actual,
174b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                      InvokeFlag flag,
175b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                      PostCallGenerator* post_call_generator = NULL);
176402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Invoke specified builtin JavaScript function. Adds an entry to
178a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the unresolved list if the name does not resolve.
179b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void InvokeBuiltin(Builtins::JavaScript id,
180b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                     InvokeFlag flag,
181b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                     PostCallGenerator* post_call_generator = NULL);
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
183791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  // Store the function for the given builtin in the target register.
184791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block  void GetBuiltinFunction(Register target, Builtins::JavaScript id);
185791712a13f1814dd3ab5d1a5ab8ff5dbc476f6d6Steve Block
186a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Store the code object for the given builtin in the target register.
187a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void GetBuiltinEntry(Register target, Builtins::JavaScript id);
188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Expression support
190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Set(Register dst, const Immediate& x);
191a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Set(const Operand& dst, const Immediate& x);
192a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
193a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compare object type for heap object.
194a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Incoming register is heap_object and outgoing register is map.
195a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CmpObjectType(Register heap_object, InstanceType type, Register map);
196a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Compare instance type for map.
198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CmpInstanceType(Register map, InstanceType type);
199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2003100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // Check if the map of an object is equal to a specified map and
2013100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // branch to label if not. Skip the smi check if not required
2023100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // (object is known to be a heap object)
2033100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  void CheckMap(Register obj,
2043100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                Handle<Map> map,
2053100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                Label* fail,
2063100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu                bool is_heap_object);
2073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu
208e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Check if the object in register heap_object is a string. Afterwards the
209e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // register map contains the object map and the register instance_type
210e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // contains the instance_type. The registers map and instance_type can be the
211e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // same in which case it contains the instance type afterwards. Either of the
212e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // registers map and instance_type can be the same as heap_object.
213e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Condition IsObjectStringType(Register heap_object,
214e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                               Register map,
215e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke                               Register instance_type);
216e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
2177f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Check if a heap object's type is in the JSObject range, not including
2187f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // JSFunction.  The object's map will be loaded in the map register.
2197f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // Any or all of the three registers may be the same.
2207f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // The contents of the scratch register will always be overwritten.
2217f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  void IsObjectJSObjectType(Register heap_object,
2227f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                            Register map,
2237f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                            Register scratch,
2247f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch                            Label* fail);
2257f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2267f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  // The contents of the scratch register will be overwritten.
2277f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch  void IsInstanceJSObjectType(Register map, Register scratch, Label* fail);
2287f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
229a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // FCmp is similar to integer cmp, but requires unsigned
230a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
231a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void FCmp();
232a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
233e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Smi tagging support.
234e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void SmiTag(Register reg) {
235e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    ASSERT(kSmiTag == 0);
2366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    ASSERT(kSmiTagSize == 1);
2376ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    add(reg, Operand(reg));
238e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
239e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void SmiUntag(Register reg) {
240e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke    sar(reg, kSmiTagSize);
241e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
242e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
243756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Modifies the register even if it does not contain a Smi!
244756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  void SmiUntag(Register reg, TypeInfo info, Label* non_smi) {
245756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    ASSERT(kSmiTagSize == 1);
246756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    sar(reg, kSmiTagSize);
247756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    if (info.IsSmi()) {
248756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick      ASSERT(kSmiTag == 0);
249756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick      j(carry, non_smi);
250756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    }
251756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
252756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
253756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Modifies the register even if it does not contain a Smi!
254756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  void SmiUntag(Register reg, Label* is_smi) {
255756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    ASSERT(kSmiTagSize == 1);
256756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    sar(reg, kSmiTagSize);
257756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    ASSERT(kSmiTag == 0);
258756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    j(not_carry, is_smi);
259756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
260756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
261756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Assumes input is a heap object.
262756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  void JumpIfNotNumber(Register reg, TypeInfo info, Label* on_not_number);
263756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
264756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Assumes input is a heap number.  Jumps on things out of range.  Also jumps
265756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // on the min negative int32.  Ignores frational parts.
266756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  void ConvertToInt32(Register dst,
267756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                      Register src,      // Can be the same as dst.
268756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                      Register scratch,  // Can be no_reg or dst, but not src.
269756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                      TypeInfo info,
270756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick                      Label* on_not_int32);
271756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
2720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void LoadPowerOf2(XMMRegister dst, Register scratch, int power);
2730d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
274402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Abort execution if argument is not a number. Used in debug code.
2756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void AbortIfNotNumber(Register object);
2766ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2776ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Abort execution if argument is not a smi. Used in debug code.
2786ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void AbortIfNotSmi(Register object);
279402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
280756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  // Abort execution if argument is a smi. Used in debug code.
281756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  void AbortIfSmi(Register object);
282756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
28380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Abort execution if argument is a string. Used in debug code.
28480d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void AbortIfNotString(Register object);
28580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
286a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Exception handling
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Push a new try handler and link into try handler chain.  The return
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // address must be pushed before calling this helper.
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void PushTryHandler(CodeLocation try_location, HandlerType type);
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
293e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Unlink the stack handler on top of the stack from the try handler chain.
294e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void PopTryHandler();
295a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
296a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Inline caching support
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generate code for checking access rights - used for security checks
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // on access to global objects across environments. The holder register
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // is left untouched, but the scratch register is clobbered.
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CheckAccessGlobalProxy(Register holder_reg,
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              Register scratch,
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                              Label* miss);
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocation support
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocate an object in new space. If the new space is exhausted control
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // continues at the gc_required label. The allocated object is returned in
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // result and end of the new object is returned in result_end. The register
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // scratch can be passed as no_reg in which case an additional object
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // reference will be added to the reloc info. The returned pointers in result
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // and result_end have not yet been tagged as heap objects. If
316d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // result_contains_top_on_entry is true the content of result is known to be
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the allocation top on entry (could be result_end from a previous call to
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // AllocateInNewSpace). If result_contains_top_on_entry is true scratch
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // should be no_reg as it is never used.
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateInNewSpace(int object_size,
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result,
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result_end,
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register scratch,
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Label* gc_required,
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          AllocationFlags flags);
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateInNewSpace(int header_size,
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          ScaleFactor element_size,
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register element_count,
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result,
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result_end,
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register scratch,
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Label* gc_required,
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          AllocationFlags flags);
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void AllocateInNewSpace(Register object_size,
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result,
338a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register result_end,
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Register scratch,
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          Label* gc_required,
341a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                          AllocationFlags flags);
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Undo allocation in new space. The object passed and objects allocated after
344a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // it will no longer be allocated. Make sure that no pointers are left to the
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // object(s) no longer allocated as they would be invalid when allocation is
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // un-done.
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void UndoAllocationInNewSpace(Register object);
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3493ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // Allocate a heap number in new space with undefined value. The
3503ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // register scratch2 can be passed as no_reg; the others must be
3513ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // valid registers. Returns tagged pointer in result register, or
3523ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  // jumps to gc_required if new space is full.
3533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void AllocateHeapNumber(Register result,
3543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                          Register scratch1,
3553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                          Register scratch2,
3563ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block                          Label* gc_required);
3573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
358d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Allocate a sequential string. All the header fields of the string object
359d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // are initialized.
360d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void AllocateTwoByteString(Register result,
361d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                             Register length,
362d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                             Register scratch1,
363d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                             Register scratch2,
364d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                             Register scratch3,
365d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                             Label* gc_required);
366d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void AllocateAsciiString(Register result,
367d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                           Register length,
368d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                           Register scratch1,
369d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                           Register scratch2,
370d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                           Register scratch3,
371d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                           Label* gc_required);
3729ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick  void AllocateAsciiString(Register result,
3739ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick                           int length,
3749ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick                           Register scratch1,
3759ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick                           Register scratch2,
3769ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick                           Label* gc_required);
377d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
378d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // Allocate a raw cons string object. Only the map field of the result is
379d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  // initialized.
380d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void AllocateConsString(Register result,
381d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                          Register scratch1,
382d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                          Register scratch2,
383d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                          Label* gc_required);
384d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void AllocateAsciiConsString(Register result,
385d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                               Register scratch1,
386d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                               Register scratch2,
387d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block                               Label* gc_required);
388d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
3898a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // All registers must be distinct.  Only current_string needs valid contents
3908a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // on entry.  All registers may be invalid on exit.  result_operand is
3918a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // unchanged, padding_chars is updated correctly.
3928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // The top of new space must contain a sequential ascii string with
3938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // padding_chars bytes free in its top word.  The sequential ascii string
3948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // current_string is concatenated to it, allocating the necessary amount
3958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // of new memory.
3968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  void AppendStringToTopOfNewSpace(
3978a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Register current_string,  // Tagged pointer to string to copy.
3988a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Register current_string_length,
3998a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Register result_pos,
4008a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Register scratch,
4018a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Register new_padding_chars,
4028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Operand operand_result,
4038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Operand operand_padding_chars,
4048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      Label* bailout);
4058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Support functions.
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if result is zero and op is negative.
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void NegativeZeroTest(Register result, Register op, Label* then_label);
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if result is zero and op is negative in code using jump targets.
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void NegativeZeroTest(CodeGenerator* cgen,
414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                        Register result,
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                        Register op,
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                        JumpTarget* then_target);
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check if result is zero and any of op1 and op2 are negative.
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Register scratch is destroyed, and it must be different from op2.
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void NegativeZeroTest(Register result, Register op1, Register op2,
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                        Register scratch, Label* then_label);
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Try to get function prototype of a function and puts the value in
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // the result register. Checks that the function really is a
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function and jumps to the miss label if the fast checks fail. The
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // function register will be untouched; the other registers may be
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // clobbered.
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void TryGetFunctionPrototype(Register function,
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register result,
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register scratch,
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Label* miss);
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Generates code for reporting that an illegal operation has
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // occurred.
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void IllegalOperation(int num_arguments);
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
43780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Picks out an array index from the hash field.
43880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // Register use:
43980d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  //   hash - holds the index's hash. Clobbered.
44080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  //   index - holds the overwritten index on exit.
44180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void IndexFromHash(Register hash, Register index);
44280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Runtime calls
445a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
446e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Call a code stub.  Generate the code if necessary.
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CallStub(CodeStub* stub);
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
449e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Call a code stub and return the code object called.  Try to generate
450e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // the code if necessary.  Do not perform a GC but instead return a retry
451e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // after GC failure.
4525913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* TryCallStub(CodeStub* stub);
453e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
454e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Tail call a code stub (jump).  Generate the code if necessary.
455d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  void TailCallStub(CodeStub* stub);
456d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
457e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Tail call a code stub (jump) and return the code object called.  Try to
458e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // generate the code if necessary.  Do not perform a GC but instead return
459e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // a retry after GC failure.
4605913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* TryTailCallStub(CodeStub* stub);
461e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
462a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return from a code stub after popping its arguments.
463a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void StubReturn(int argc);
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
465a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Call a runtime routine.
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CallRuntime(Runtime::Function* f, int num_arguments);
467b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void CallRuntimeSaveDoubles(Runtime::FunctionId id);
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4694515c472dc3e5ed2448a564600976759e569a0a8Leon Clarke  // Call a runtime function, returning the CodeStub object called.
470e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Try to generate the stub code if necessary.  Do not perform a GC
471e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // but instead return a retry after GC failure.
4725913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* TryCallRuntime(Runtime::Function* f,
4735913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                              int num_arguments);
474e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Convenience function: Same as above, but takes the fid instead.
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void CallRuntime(Runtime::FunctionId id, int num_arguments);
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
478e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Convenience function: Same as above, but takes the fid instead.
4795913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* TryCallRuntime(Runtime::FunctionId id,
4805913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                              int num_arguments);
481e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
482bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  // Convenience function: call an external reference.
483bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch  void CallExternalReference(ExternalReference ref, int num_arguments);
484bb769b257e753aafcbd96767abb2abc645eaa20cBen Murdoch
485a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Tail call of a runtime routine (jump).
4866ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Like JumpToExternalReference, but also takes care of passing the number
4876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // of parameters.
4886ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void TailCallExternalReference(const ExternalReference& ext,
4896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 int num_arguments,
4906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                 int result_size);
4916ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
4928a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Tail call of a runtime routine (jump). Try to generate the code if
4938a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // necessary. Do not perform a GC but instead return a retry after GC failure.
4948a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  MUST_USE_RESULT MaybeObject* TryTailCallExternalReference(
4958a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang      const ExternalReference& ext, int num_arguments, int result_size);
4968a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
4976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Convenience function: tail call a runtime routine (jump).
4986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void TailCallRuntime(Runtime::FunctionId fid,
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                       int num_arguments,
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                       int result_size);
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5028a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Convenience function: tail call a runtime routine (jump). Try to generate
5038a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // the code if necessary. Do not perform a GC but instead return a retry after
5048a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // GC failure.
5058a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  MUST_USE_RESULT MaybeObject* TryTailCallRuntime(Runtime::FunctionId fid,
5068a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang                                                  int num_arguments,
5078a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang                                                  int result_size);
5088a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
5096ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Before calling a C-function from generated code, align arguments on stack.
5106ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // After aligning the frame, arguments must be stored in esp[0], esp[4],
5116ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // etc., not pushed. The argument count assumes all arguments are word sized.
5126ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Some compilers/platforms require the stack to be aligned when calling
5136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // C++ code.
5146ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Needs a scratch register to do some arithmetic. This register will be
5156ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // trashed.
5166ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void PrepareCallCFunction(int num_arguments, Register scratch);
5176ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5186ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Calls a C function and cleans up the space for arguments allocated
5196ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // by PrepareCallCFunction. The called function is not allowed to trigger a
5206ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // garbage collection, since that might move the code and invalidate the
5216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // return address (unless this is somehow accounted for by the called
5226ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // function).
5236ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CallCFunction(ExternalReference function, int num_arguments);
5246ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CallCFunction(Register function, int num_arguments);
5256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5265913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  // Prepares stack to put arguments (aligns and so on). Reserves
5275913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  // space for return value if needed (assumes the return value is a handle).
5285913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  // Uses callee-saved esi to restore stack state after call. Arguments must be
5298a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // stored in ApiParameterOperand(0), ApiParameterOperand(1) etc. Saves
5308a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // context (esi).
5318a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  void PrepareCallApiFunction(int argc, Register scratch);
532d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
53390bac256d9f48d4ee52d0e08bf0e5cad57b3c51cRussell Brenner  // Calls an API function. Allocates HandleScope, extracts
5345913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  // returned value from handle and propagates exceptions.
5358a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // Clobbers ebx, edi and caller-save registers. Restores context.
5368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  // On return removes stack_space * kPointerSize (GCed).
5378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  MaybeObject* TryCallApiFunctionAndReturn(ApiFunction* function,
5388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang                                           int stack_space);
539e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Jump to a runtime routine.
5416ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void JumpToExternalReference(const ExternalReference& ext);
542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  MaybeObject* TryJumpToExternalReference(const ExternalReference& ext);
5448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
545a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
546a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
547a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Utilities
548a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
549a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Ret();
550a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
551e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Emit code to discard a non-negative number of pointer-sized elements
552e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // from the stack, clobbering only the esp register.
553e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void Drop(int element_count);
554e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
555e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void Call(Label* target) { call(target); }
556e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
557b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Emit call to the code we are currently generating.
558b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void CallSelf() {
559b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
560b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    call(self, RelocInfo::CODE_TARGET);
561b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
562b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
5630d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  // Move if the registers are not identical.
5640d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  void Move(Register target, Register source);
5650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
566e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  void Move(Register target, Handle<Object> value);
567e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
568a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<Object> CodeObject() { return code_object_; }
569a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
570a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
571a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
572a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // StatsCounter support
573a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
574a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void SetCounter(StatsCounter* counter, int value);
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void IncrementCounter(StatsCounter* counter, int value);
576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void DecrementCounter(StatsCounter* counter, int value);
577d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void IncrementCounter(Condition cc, StatsCounter* counter, int value);
578d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void DecrementCounter(Condition cc, StatsCounter* counter, int value);
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
580a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
581a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // ---------------------------------------------------------------------------
582a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Debugging
583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Calls Abort(msg) if the condition cc is not satisfied.
585a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Use --debug_code to enable.
586a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Assert(Condition cc, const char* msg);
587a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
588756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  void AssertFastElements(Register elements);
589756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick
590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Like Assert(), but always enabled.
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Check(Condition cc, const char* msg);
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Print a message to stdout and abort execution.
594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Abort(const char* msg);
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5966ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // Check that the stack is aligned.
5976ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  void CheckStackAlignment();
5986ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Verify restrictions about code generated in stubs.
600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_generating_stub(bool value) { generating_stub_ = value; }
601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool generating_stub() { return generating_stub_; }
602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; }
603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool allow_stub_calls() { return allow_stub_calls_; }
604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
605d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // ---------------------------------------------------------------------------
606d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // String utilities.
607d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
608402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // Check whether the instance type represents a flat ascii string. Jump to the
609402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // label if not. If the instance type can be scratched specify same register
610402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  // for both instance type and scratch.
611402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu  void JumpIfInstanceTypeIsNotSequentialAscii(Register instance_type,
612402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu                                              Register scratch,
6136ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                              Label* on_not_flat_ascii_string);
614402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
615d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // Checks if both objects are sequential ASCII strings, and jumps to label
616d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  // if either is not.
617d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke  void JumpIfNotBothSequentialAsciiStrings(Register object1,
618d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                           Register object2,
619d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                           Register scratch1,
620d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke                                           Register scratch2,
6216ded16be15dd865a9b21ea304d5273c8be299c87Steve Block                                           Label* on_not_flat_ascii_strings);
622d91b9f7d46489a9ee00f9cb415630299c76a502bLeon Clarke
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool generating_stub_;
625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool allow_stub_calls_;
6263100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  // This handle will be patched with the code object on installation.
6273100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  Handle<Object> code_object_;
628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Helper functions for generating invokes.
630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void InvokePrologue(const ParameterCount& expected,
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      const ParameterCount& actual,
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      Handle<Code> code_constant,
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      const Operand& code_operand,
634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                      Label* done,
635b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                      InvokeFlag flag,
636b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                      PostCallGenerator* post_call_generator = NULL);
637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Activation support.
639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void EnterFrame(StackFrame::Type type);
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LeaveFrame(StackFrame::Type type);
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
64280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  void EnterExitFramePrologue();
643b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  void EnterExitFrameEpilogue(int argc, bool save_doubles);
644d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
6458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  void LeaveExitFrameEpilogue();
6468a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Allocation support helpers.
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void LoadAllocationTopHelper(Register result,
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               Register scratch,
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                               AllocationFlags flags);
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void UpdateAllocationTopHelper(Register result_end, Register scratch);
652e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
653e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Helper for PopHandleScope.  Allowed to perform a GC and returns
654e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // NULL if gc_allowed.  Does not perform a GC if !gc_allowed, and
655e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // possibly returns a failure object indicating an allocation failure.
6565913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck  MUST_USE_RESULT MaybeObject* PopHandleScopeHelper(Register saved,
6575913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                                    Register scratch,
6585913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck                                                    bool gc_allowed);
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
662b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochtemplate <typename LabelType>
663b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochvoid MacroAssembler::InNewSpace(Register object,
664b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                Register scratch,
665b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                Condition cc,
666b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch                                LabelType* branch) {
667b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  ASSERT(cc == equal || cc == not_equal);
668b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  if (Serializer::enabled()) {
669b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Can't do arithmetic on external references if it might get serialized.
670b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    mov(scratch, Operand(object));
671b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // The mask isn't really an address.  We load it as an external reference in
672b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // case the size of the new space is different between the snapshot maker
673b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // and the running system.
674b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    and_(Operand(scratch), Immediate(ExternalReference::new_space_mask()));
675b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    cmp(Operand(scratch), Immediate(ExternalReference::new_space_start()));
676b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    j(cc, branch);
677b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  } else {
678b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    int32_t new_space_start = reinterpret_cast<int32_t>(
679b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch        ExternalReference::new_space_start().address());
680b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    lea(scratch, Operand(object, -new_space_start));
681b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    and_(scratch, Heap::NewSpaceMask());
682b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    j(cc, branch);
683b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
684b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch}
685b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
686b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The code patcher is used to patch (typically) small parts of code e.g. for
688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// debugging and other types of instrumentation. When using the code patcher
689a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the exact number of bytes specified must be emitted. Is not legal to emit
690a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// relocation information. If any of these constraints are violated it causes
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// an assertion.
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass CodePatcher {
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  CodePatcher(byte* address, int size);
695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  virtual ~CodePatcher();
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Macro assembler to emit code.
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MacroAssembler* masm() { return &masm_; }
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  byte* address_;  // The address of the code being patched.
702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int size_;  // Number of bytes of the expected patch size.
703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  MacroAssembler masm_;  // Macro assembler used to generate the code.
704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
707b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// Helper class for generating code or data associated with the code
708b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// right after a call instruction. As an example this can be used to
709b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch// generate safepoint data after calls for crankshaft.
710b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass PostCallGenerator {
711b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch public:
712b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  PostCallGenerator() { }
713b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual ~PostCallGenerator() { }
714b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  virtual void Generate() = 0;
715b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch};
716b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
717b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -----------------------------------------------------------------------------
719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Static helper functions.
720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Generate an Operand for loading a field from an object.
722a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline Operand FieldOperand(Register object, int offset) {
723a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Operand(object, offset - kHeapObjectTag);
724a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
725a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
726a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
727a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Generate an Operand for loading an indexed field from an object.
728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockstatic inline Operand FieldOperand(Register object,
729a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                   Register index,
730a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                   ScaleFactor scale,
731a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                                   int offset) {
732a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return Operand(object, index, scale, offset - kHeapObjectTag);
733a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
7358a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7368a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangstatic inline Operand ContextOperand(Register context, int index) {
7378a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return Operand(context, Context::SlotOffset(index));
7388a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
7398a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7408a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7418a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wangstatic inline Operand GlobalObjectOperand() {
7428a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang  return ContextOperand(esi, Context::GLOBAL_INDEX);
7438a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang}
7448a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7458a31eba00023874d4a1dcdc5f411cc4336776874Shimeng (Simon) Wang
7465913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck// Generates an Operand for saving parameters after PrepareCallApiFunction.
7475913587db4c6bab03d97bfe44b06289fd6d7270dJohn ReckOperand ApiParameterOperand(int index);
7485913587db4c6bab03d97bfe44b06289fd6d7270dJohn Reck
749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#ifdef GENERATED_CODE_COVERAGE
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockextern void LogGeneratedCodeCoverage(const char* file_line);
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CODE_COVERAGE_STRINGIFY(x) #x
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ACCESS_MASM(masm) {                                               \
756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    byte* ia32_coverage_function =                                        \
757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        reinterpret_cast<byte*>(FUNCTION_ADDR(LogGeneratedCodeCoverage)); \
758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->pushfd();                                                       \
759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->pushad();                                                       \
760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->push(Immediate(reinterpret_cast<int>(&__FILE_LINE__)));         \
761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->call(ia32_coverage_function, RelocInfo::RUNTIME_ENTRY);         \
762a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->pop(eax);                                                       \
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->popad();                                                        \
764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    masm->popfd();                                                        \
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }                                                                       \
766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  masm->
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#else
768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define ACCESS_MASM(masm) masm->
769a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif
770a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block} }  // namespace v8::internal
773a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
774a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#endif  // V8_IA32_MACRO_ASSEMBLER_IA32_H_
775