1f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
55ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#ifndef V8_ARM_MACRO_ASSEMBLER_ARM_H_
65ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#define V8_ARM_MACRO_ASSEMBLER_ARM_H_
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/assembler.h"
9b4ef18e93b120b995e067ba72707b62a448eeed6machenbach@chromium.org#include "src/bailout-reason.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/frames.h"
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/globals.h"
1243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1371affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
1471affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
165c838251403b0be9a882540f1922577abba4c872ager@chromium.org// ----------------------------------------------------------------------------
175c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Static helper functions
185c838251403b0be9a882540f1922577abba4c872ager@chromium.org
195c838251403b0be9a882540f1922577abba4c872ager@chromium.org// Generate a MemOperand for loading a field from an object.
201b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline MemOperand FieldMemOperand(Register object, int offset) {
215c838251403b0be9a882540f1922577abba4c872ager@chromium.org  return MemOperand(object, offset - kHeapObjectTag);
225c838251403b0be9a882540f1922577abba4c872ager@chromium.org}
235c838251403b0be9a882540f1922577abba4c872ager@chromium.org
2443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Give alias names to registers
26cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.orgconst Register cp = { kRegister_r7_Code };  // JavaScript context pointer.
27cc536058448cdb26fedf76ce62f2ce91480f2ae3yangguo@chromium.orgconst Register pp = { kRegister_r8_Code };  // Constant pool pointer.
283d079fe881245e49c7ba803b54b4fe6d4b46113cmachenbach@chromium.orgconst Register kRootRegister = { kRegister_r10_Code };  // Roots array pointer.
2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
30c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org// Flags used for AllocateHeapNumber
31c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.orgenum TaggingMode {
32c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Tag the result.
33c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  TAG_RESULT,
34c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Don't tag
35c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  DONT_TAG_RESULT
36c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org};
37720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org
3832d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org
39c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comenum RememberedSetAction { EMIT_REMEMBERED_SET, OMIT_REMEMBERED_SET };
40c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comenum SmiCheck { INLINE_SMI_CHECK, OMIT_SMI_CHECK };
41196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.orgenum PointersToHereCheck {
42196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  kPointersToHereMaybeInteresting,
43196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  kPointersToHereAreAlwaysInteresting
44196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org};
45c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.comenum LinkRegisterStatus { kLRHasNotBeenSaved, kLRHasBeenSaved };
46c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
47c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
481e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.orgRegister GetRegisterThatIsNotOneOf(Register reg1,
491e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                                   Register reg2 = no_reg,
501e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                                   Register reg3 = no_reg,
511e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                                   Register reg4 = no_reg,
521e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                                   Register reg5 = no_reg,
531e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                                   Register reg6 = no_reg);
541e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
551e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
56efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org#ifdef DEBUG
57efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.orgbool AreAliased(Register reg1,
58efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org                Register reg2,
59efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org                Register reg3 = no_reg,
60efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org                Register reg4 = no_reg,
61efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org                Register reg5 = no_reg,
629bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                Register reg6 = no_reg,
639bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                Register reg7 = no_reg,
649bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                Register reg8 = no_reg);
65efdb9d70bddd496ceb6a281dadcc065efbce37a1yangguo@chromium.org#endif
66c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
67c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
6889e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.orgenum TargetAddressStorageMode {
6989e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  CAN_INLINE_TARGET_ADDRESS,
7089e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  NEVER_INLINE_TARGET_ADDRESS
7189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org};
7289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org
7343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// MacroAssembler implements a collection of frequently used macros.
7443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass MacroAssembler: public Assembler {
7543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
76c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // The isolate parameter can be NULL if the macro assembler should
77c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // not use isolate-dependent functionality. In this case, it's the
78c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // responsibility of the caller to never invoke such function on the
79c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  // macro assembler.
80c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  MacroAssembler(Isolate* isolate, void* buffer, int size);
8143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
82d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
83d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Returns the size of a call in instructions. Note, the value returned is
84d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // only valid as long as no entries are added to the constant pool between
85d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // checking the call size and emitting the actual call.
867c2628c3f0353f0558760c3ca442f934263ea766kmillikin@chromium.org  static int CallSize(Register target, Condition cond = al);
87471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  int CallSize(Address target, RelocInfo::Mode rmode, Condition cond = al);
889e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org  int CallStubSize(CodeStub* stub,
899e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                   TypeFeedbackId ast_id = TypeFeedbackId::None(),
909e41f9ecf5042292a9efcb36e264b37621199553machenbach@chromium.org                   Condition cond = al);
91a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org  static int CallSizeNotPredictableCodeSize(Isolate* isolate,
92a86d416fb652b1936026eee315eccd4f17ca1002machenbach@chromium.org                                            Address target,
93471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                                            RelocInfo::Mode rmode,
94471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org                                            Condition cond = al);
95d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
96d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  // Jump, Call, and Ret pseudo instructions implementing inter-working.
97d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  void Jump(Register target, Condition cond = al);
98d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  void Jump(Address target, RelocInfo::Mode rmode, Condition cond = al);
99d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  void Jump(Handle<Code> code, RelocInfo::Mode rmode, Condition cond = al);
100d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  void Call(Register target, Condition cond = al);
10189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  void Call(Address target, RelocInfo::Mode rmode,
10289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org            Condition cond = al,
10389e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org            TargetAddressStorageMode mode = CAN_INLINE_TARGET_ADDRESS);
104471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org  int CallSize(Handle<Code> code,
105471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org               RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
106471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org               TypeFeedbackId ast_id = TypeFeedbackId::None(),
107471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org               Condition cond = al);
1088e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  void Call(Handle<Code> code,
1094f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org            RelocInfo::Mode rmode = RelocInfo::CODE_TARGET,
110471f2f1d24adb4bad1edc3bf0ee35092486de187mstarzinger@chromium.org            TypeFeedbackId ast_id = TypeFeedbackId::None(),
11189e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org            Condition cond = al,
11289e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org            TargetAddressStorageMode mode = CAN_INLINE_TARGET_ADDRESS);
11365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org  void Ret(Condition cond = al);
1140c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
1150c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // Emit code to discard a non-negative number of pointer-sized elements
1160c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  // from the stack, clobbering only the sp register.
1170c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org  void Drop(int count, Condition cond = al);
1180c20e676f8a0209982ff89e5a9c707771748a585fschneider@chromium.org
119023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  void Ret(int drop, Condition cond = al);
120357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
121357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // Swap two registers.  If the scratch register is omitted then a slightly
122357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // less efficient form using xor instead of mov is emitted.
12330ce411529579186181838984710b0b0980857aaricow@chromium.org  void Swap(Register reg1,
12430ce411529579186181838984710b0b0980857aaricow@chromium.org            Register reg2,
12530ce411529579186181838984710b0b0980857aaricow@chromium.org            Register scratch = no_reg,
12630ce411529579186181838984710b0b0980857aaricow@chromium.org            Condition cond = al);
127357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
12870d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org  void Mls(Register dst, Register src1, Register src2, Register srcA,
12970d11c79c7833b9ab1ee185625fcf707b9480a40machenbach@chromium.org           Condition cond = al);
1302c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  void And(Register dst, Register src1, const Operand& src2,
1312c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org           Condition cond = al);
1322c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  void Ubfx(Register dst, Register src, int lsb, int width,
1332c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org            Condition cond = al);
1342c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org  void Sbfx(Register dst, Register src, int lsb, int width,
1352c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org            Condition cond = al);
1369ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // The scratch register is not used for ARMv7.
1379ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // scratch can be the same register as src (in which case it is trashed), but
1389ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // not the same as dst.
1399ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  void Bfi(Register dst,
1409ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org           Register src,
1419ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org           Register scratch,
1429ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org           int lsb,
1439ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org           int width,
1449ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org           Condition cond = al);
14533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  void Bfc(Register dst, Register src, int lsb, int width, Condition cond = al);
146ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org  void Usat(Register dst, int satpos, const Operand& src,
147ed78ffdee6ea4f4f94420b464e7377b610fdac2ffschneider@chromium.org            Condition cond = al);
1482c186ca6690a1cb19ec7584e71f167234587c87cwhesse@chromium.org
14913bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void Call(Label* target);
150594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Push(Register src) { push(src); }
151594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Pop(Register dst) { pop(dst); }
1528e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1538e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // Register move. May do nothing if the registers are identical.
15413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void Move(Register dst, Handle<Object> value);
1553cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  void Move(Register dst, Register src, Condition cond = al);
1565e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  void Move(Register dst, const Operand& src, SBit sbit = LeaveCC,
1575e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org            Condition cond = al) {
1585e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    if (!src.is_reg() || !src.rm().is(dst) || sbit != LeaveCC) {
1595e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org      mov(dst, src, sbit, cond);
1605e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org    }
1617d299ad4dc0ca26e0017b190b48362ad71328ce4machenbach@chromium.org  }
162a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  void Move(DwVfpRegister dst, DwVfpRegister src);
1638e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
164935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  void Load(Register dst, const MemOperand& src, Representation r);
165935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org  void Store(Register src, const MemOperand& dst, Representation r);
166935a7790c70d49e252069bc2d34eaa72f8c6677fmachenbach@chromium.org
167ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org  // Load an object from the root table.
168ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org  void LoadRoot(Register destination,
169ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org                Heap::RootListIndex index,
170ab99eea3d9d0cc20698ebb39bf0fb80e3e66bffcager@chromium.org                Condition cond = al);
171720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  // Store an object to the root table.
172720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  void StoreRoot(Register source,
173720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org                 Heap::RootListIndex index,
174720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org                 Condition cond = al);
17541044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
176c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // ---------------------------------------------------------------------------
177c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // GC Support
178c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
179c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void IncrementalMarkingRecordWriteHelper(Register object,
180c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                           Register value,
181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                           Register address);
182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  enum RememberedSetFinalAction {
184c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    kReturnAtEnd,
185c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    kFallThroughAtEnd
186c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  };
187c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
188c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Record in the remembered set the fact that we have a pointer to new space
189c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // at the address pointed to by the addr register.  Only works if addr is not
190c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // in new space.
191c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void RememberedSetHelper(Register object,  // Used for debug code.
192c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Register addr,
193c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Register scratch,
194c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           SaveFPRegsMode save_fp,
195c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           RememberedSetFinalAction and_then);
196c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
197c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void CheckPageFlag(Register object,
198c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     Register scratch,
199c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     int mask,
200c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     Condition cc,
201c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     Label* condition_met);
202c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
203f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org  void CheckMapDeprecated(Handle<Map> map,
204f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                          Register scratch,
205f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org                          Label* if_deprecated);
206f005df6c3232e65028420519fbab7284bc9b33aedanno@chromium.org
207c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if object is in new space.  Jumps if the object is not in new space.
208c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The register scratch can be object itself, but scratch will be clobbered.
209c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void JumpIfNotInNewSpace(Register object,
210c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Register scratch,
211c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                           Label* branch) {
212c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    InNewSpace(object, scratch, ne, branch);
213c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
214ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org
215c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if object is in new space.  Jumps if the object is in new space.
216c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The register scratch can be object itself, but it will be clobbered.
217c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void JumpIfInNewSpace(Register object,
218c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        Register scratch,
219c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        Label* branch) {
220c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    InNewSpace(object, scratch, eq, branch);
221c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
222ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org
223c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if an object has a given incremental marking color.
224c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void HasColor(Register object,
225c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                Register scratch0,
226c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                Register scratch1,
227c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                Label* has_color,
228c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                int first_bit,
229c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                int second_bit);
23069ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
231c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void JumpIfBlack(Register object,
2325ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org                   Register scratch0,
233c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                   Register scratch1,
234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                   Label* on_black);
235c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
236c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Checks the color of an object.  If the object is already grey or black
237c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // then we just fall through, since it is already live.  If it is white and
238c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // we can determine that it doesn't need to be scanned, then we just mark it
239c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // black and fall through.  For the rest we jump to the label so the
240c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // incremental marker can fix its assumptions.
241c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void EnsureNotWhite(Register object,
242c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Register scratch1,
243c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Register scratch2,
244c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Register scratch3,
245c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                      Label* object_is_white_and_not_data);
24643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2472efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // Detects conservatively whether an object is data-only, i.e. it does need to
248c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // be scanned by the garbage collector.
249c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void JumpIfDataObject(Register value,
250c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        Register scratch,
251c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        Label* not_data_object);
252c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
253c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Notify the garbage collector that we wrote a pointer into an object.
254c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // |object| is the object being stored into, |value| is the object being
255c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // stored.  value and scratch registers are clobbered by the operation.
256c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // The offset is the offset from the start of the object, not the offset from
257c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the tagged HeapObject pointer.  For use with FieldOperand(reg, off).
258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void RecordWriteField(
259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register object,
260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      int offset,
261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register value,
262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register scratch,
263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      LinkRegisterStatus lr_status,
264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SaveFPRegsMode save_fp,
265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
266196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      SmiCheck smi_check = INLINE_SMI_CHECK,
267196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      PointersToHereCheck pointers_to_here_check_for_value =
268196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          kPointersToHereMaybeInteresting);
269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // As above, but the offset has the tag presubtracted.  For use with
271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // MemOperand(reg, off).
272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  inline void RecordWriteContextSlot(
273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register context,
274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      int offset,
275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register value,
276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register scratch,
277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      LinkRegisterStatus lr_status,
278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SaveFPRegsMode save_fp,
279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
280196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      SmiCheck smi_check = INLINE_SMI_CHECK,
281196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      PointersToHereCheck pointers_to_here_check_for_value =
282196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          kPointersToHereMaybeInteresting) {
283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    RecordWriteField(context,
284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     offset + kHeapObjectTag,
285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     value,
286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     scratch,
287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     lr_status,
288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     save_fp,
289c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                     remembered_set_action,
290196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                     smi_check,
291196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org                     pointers_to_here_check_for_value);
292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
294196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org  void RecordWriteForMap(
295196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      Register object,
296196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      Register map,
297196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      Register dst,
298196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      LinkRegisterStatus lr_status,
299196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      SaveFPRegsMode save_fp);
300196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org
301c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // For a given |object| notify the garbage collector that the slot |address|
302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // has been written.  |value| is the object being stored. The value and
303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // address registers are clobbered by the operation.
304c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void RecordWrite(
305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register object,
306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register address,
307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Register value,
308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      LinkRegisterStatus lr_status,
309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      SaveFPRegsMode save_fp,
310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      RememberedSetAction remembered_set_action = EMIT_REMEMBERED_SET,
311196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      SmiCheck smi_check = INLINE_SMI_CHECK,
312196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org      PointersToHereCheck pointers_to_here_check_for_value =
313196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org          kPointersToHereMaybeInteresting);
31469ea3965ef6e0d3f020a402cf7e6b96b9cb651aekmillikin@chromium.org
3156d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  // Push a handle.
3166d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org  void Push(Handle<Object> handle);
31709d7ab5aba54ebac170eac755664c45eefb0be7dulan@chromium.org  void Push(Smi* smi) { Push(Handle<Smi>(smi, isolate())); }
3186d786c9805481bd13ecb29c3155540f2f32950e1svenpanne@chromium.org
319c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  // Push two registers.  Pushes leftmost register first (to highest address).
320c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  void Push(Register src1, Register src2, Condition cond = al) {
321e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src1.is(src2));
322c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org    if (src1.code() > src2.code()) {
323c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org      stm(db_w, sp, src1.bit() | src2.bit(), cond);
324c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org    } else {
325c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org      str(src1, MemOperand(sp, 4, NegPreIndex), cond);
326c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org      str(src2, MemOperand(sp, 4, NegPreIndex), cond);
327c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org    }
328c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  }
329c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org
330c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  // Push three registers.  Pushes leftmost register first (to highest address).
331c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  void Push(Register src1, Register src2, Register src3, Condition cond = al) {
332e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src1.is(src2));
333e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src2.is(src3));
334e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src1.is(src3));
335c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org    if (src1.code() > src2.code()) {
336c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org      if (src2.code() > src3.code()) {
337c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org        stm(db_w, sp, src1.bit() | src2.bit() | src3.bit(), cond);
338c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org      } else {
339c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org        stm(db_w, sp, src1.bit() | src2.bit(), cond);
340c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org        str(src3, MemOperand(sp, 4, NegPreIndex), cond);
341c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org      }
342c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org    } else {
343c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org      str(src1, MemOperand(sp, 4, NegPreIndex), cond);
344c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org      Push(src2, src3, cond);
345c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org    }
346c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  }
347c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org
348c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  // Push four registers.  Pushes leftmost register first (to highest address).
349394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  void Push(Register src1,
350394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com            Register src2,
351394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com            Register src3,
352394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com            Register src4,
353394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com            Condition cond = al) {
354e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src1.is(src2));
355e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src2.is(src3));
356e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src1.is(src3));
357e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src1.is(src4));
358e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src2.is(src4));
359e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src3.is(src4));
360c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org    if (src1.code() > src2.code()) {
361c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org      if (src2.code() > src3.code()) {
362c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org        if (src3.code() > src4.code()) {
363c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org          stm(db_w,
364c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org              sp,
365c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org              src1.bit() | src2.bit() | src3.bit() | src4.bit(),
366c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org              cond);
367c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org        } else {
368c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org          stm(db_w, sp, src1.bit() | src2.bit() | src3.bit(), cond);
369c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org          str(src4, MemOperand(sp, 4, NegPreIndex), cond);
370c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org        }
371c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org      } else {
372c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org        stm(db_w, sp, src1.bit() | src2.bit(), cond);
373c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org        Push(src3, src4, cond);
374c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org      }
375c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org    } else {
376c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org      str(src1, MemOperand(sp, 4, NegPreIndex), cond);
377c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org      Push(src2, src3, src4, cond);
378c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org    }
379c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org  }
380c34f5802a37a9fa2ce8f3929d1d5159ddcf04ff3lrn@chromium.org
3819ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // Pop two registers. Pops rightmost register first (from lower address).
3829ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  void Pop(Register src1, Register src2, Condition cond = al) {
383e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src1.is(src2));
3849ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    if (src1.code() > src2.code()) {
3859ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      ldm(ia_w, sp, src1.bit() | src2.bit(), cond);
3869ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    } else {
3879ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      ldr(src2, MemOperand(sp, 4, PostIndex), cond);
3889ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org      ldr(src1, MemOperand(sp, 4, PostIndex), cond);
3899ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org    }
3909ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  }
3919ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
392394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Pop three registers.  Pops rightmost register first (from lower address).
393394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  void Pop(Register src1, Register src2, Register src3, Condition cond = al) {
394e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src1.is(src2));
395e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src2.is(src3));
396e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src1.is(src3));
397394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (src1.code() > src2.code()) {
398394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      if (src2.code() > src3.code()) {
399394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        ldm(ia_w, sp, src1.bit() | src2.bit() | src3.bit(), cond);
400394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      } else {
401394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        ldr(src3, MemOperand(sp, 4, PostIndex), cond);
402394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        ldm(ia_w, sp, src1.bit() | src2.bit(), cond);
403394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      }
404394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    } else {
405394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Pop(src2, src3, cond);
406e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org      ldr(src1, MemOperand(sp, 4, PostIndex), cond);
407394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
408394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
409394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
410394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Pop four registers.  Pops rightmost register first (from lower address).
411394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  void Pop(Register src1,
412394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com           Register src2,
413394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com           Register src3,
414394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com           Register src4,
415394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com           Condition cond = al) {
416e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src1.is(src2));
417e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src2.is(src3));
418e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src1.is(src3));
419e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src1.is(src4));
420e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src2.is(src4));
421e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!src3.is(src4));
422394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    if (src1.code() > src2.code()) {
423394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      if (src2.code() > src3.code()) {
424394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        if (src3.code() > src4.code()) {
425394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          ldm(ia_w,
426394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com              sp,
427394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com              src1.bit() | src2.bit() | src3.bit() | src4.bit(),
428394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com              cond);
429394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        } else {
430394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          ldr(src4, MemOperand(sp, 4, PostIndex), cond);
431394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com          ldm(ia_w, sp, src1.bit() | src2.bit() | src3.bit(), cond);
432394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        }
433394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      } else {
434394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        Pop(src3, src4, cond);
435394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com        ldm(ia_w, sp, src1.bit() | src2.bit(), cond);
436394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      }
437394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    } else {
438394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      Pop(src2, src3, src4, cond);
439394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com      ldr(src1, MemOperand(sp, 4, PostIndex), cond);
440394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    }
441394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  }
442394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
4439ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  // Push a fixed frame, consisting of lr, fp, constant pool (if
4449ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  // FLAG_enable_ool_constant_pool), context and JS function / marker id if
4459ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  // marker_reg is a valid register.
4469ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  void PushFixedFrame(Register marker_reg = no_reg);
4479ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  void PopFixedFrame(Register marker_reg = no_reg);
4489ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org
449a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // Push and pop the registers that can hold pointers, as defined by the
450a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  // RegList constant kSafepointSavedRegisters.
451a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PushSafepointRegisters();
452a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void PopSafepointRegisters();
4533a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Store value in register src in the safepoint stack slot for
4543a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // register dst.
4553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void StoreToSafepointRegisterSlot(Register src, Register dst);
4563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Load the value of the src register from its safepoint stack slot
4573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // into register dst.
4583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void LoadFromSafepointRegisterSlot(Register dst, Register src);
459a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
4609155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // Load two consecutive registers with two consecutive memory locations.
4619155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  void Ldrd(Register dst1,
4629155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org            Register dst2,
4639155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org            const MemOperand& src,
4649155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org            Condition cond = al);
4659155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
4669155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  // Store two consecutive registers to two consecutive memory locations.
4679155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org  void Strd(Register src1,
4689155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org            Register src2,
4699155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org            const MemOperand& dst,
4709155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org            Condition cond = al);
4719155e252524a2bf92aecd27493feafed86702312kmillikin@chromium.org
472e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Ensure that FPSCR contains values needed by JavaScript.
473e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // We need the NaNModeControlBit to be sure that operations like
474e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // vadd and vsub generate the Canonical NaN (if a NaN must be generated).
475e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // In VFP3 it will be always the Canonical NaN.
476e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // In VFP2 it will be either the Canonical NaN or the negative version
477e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // of the Canonical NaN. It doesn't matter if we have two values. The aim
478e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // is to be sure to never generate the hole NaN.
479e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  void VFPEnsureFPSCRState(Register scratch);
480e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
481e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // If the value is a NaN, canonicalize the value else, do nothing.
482528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void VFPCanonicalizeNaN(const DwVfpRegister dst,
483528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                          const DwVfpRegister src,
4842f877ace3ac6432b1ce44abd553cd3ff97321680hpayer@chromium.org                          const Condition cond = al);
485528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void VFPCanonicalizeNaN(const DwVfpRegister value,
486528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                          const Condition cond = al) {
487528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org    VFPCanonicalizeNaN(value, value, cond);
488528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  }
489e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
490c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Compare double values and move the result to the normal condition flags.
491c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void VFPCompareAndSetFlags(const DwVfpRegister src1,
492c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                             const DwVfpRegister src2,
493c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                             const Condition cond = al);
494c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void VFPCompareAndSetFlags(const DwVfpRegister src1,
495c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                             const double src2,
496c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                             const Condition cond = al);
497c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
498c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Compare double values and then load the fpscr flags to a register.
499c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void VFPCompareAndLoadFlags(const DwVfpRegister src1,
500c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                              const DwVfpRegister src2,
501c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                              const Register fpscr_flags,
502c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                              const Condition cond = al);
503c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void VFPCompareAndLoadFlags(const DwVfpRegister src1,
504c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                              const double src2,
505c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                              const Register fpscr_flags,
506c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                              const Condition cond = al);
507c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
5083cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org  void Vmov(const DwVfpRegister dst,
5093cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org            const double imm,
51071fc3467b5396c27d0b701d88e196e88c78d8864mstarzinger@chromium.org            const Register scratch = no_reg);
5113cf47318da216c319ecf1f7a59de23455f117197vegorov@chromium.org
512fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  void VmovHigh(Register dst, DwVfpRegister src);
513fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  void VmovHigh(DwVfpRegister dst, Register src);
514fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  void VmovLow(Register dst, DwVfpRegister src);
515fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  void VmovLow(DwVfpRegister dst, Register src);
516fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org
51732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // Loads the number from object into dst register.
51832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // If |object| is neither smi nor heap number, |not_number| is jumped to
51932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // with |object| still intact.
52032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  void LoadNumber(Register object,
521fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                  LowDwVfpRegister dst,
52232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                  Register heap_number_map,
52332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                  Register scratch,
52432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                  Label* not_number);
52532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
52632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // Loads the number from object into double_dst in the double format.
52732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // Control will jump to not_int32 if the value cannot be exactly represented
52832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // by a 32-bit integer.
52932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // Floating point value in the 32-bit integer range that are not exact integer
53032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // won't be loaded.
53132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  void LoadNumberAsInt32Double(Register object,
53232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                               DwVfpRegister double_dst,
53332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                               Register heap_number_map,
53432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                               Register scratch,
535fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                               LowDwVfpRegister double_scratch,
53632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                               Label* not_int32);
53732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
53832d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // Loads the number from object into dst as a 32-bit integer.
53932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // Control will jump to not_int32 if the object cannot be exactly represented
54032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // by a 32-bit integer.
54132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // Floating point value in the 32-bit integer range that are not exact integer
54232d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // won't be converted.
54332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  void LoadNumberAsInt32(Register object,
54432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                         Register dst,
54532d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                         Register heap_number_map,
54632d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                         Register scratch,
54732d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                         DwVfpRegister double_scratch0,
548fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                         LowDwVfpRegister double_scratch1,
54932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                         Label* not_int32);
55032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
551c9913f099d68d3604e53b19d0fc5abe309143bdcbmeurer@chromium.org  // Generates function and stub prologue code.
552285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org  void StubPrologue();
553285f85a5a149f36516a20200a76899651dd95fb6machenbach@chromium.org  void Prologue(bool code_pre_aging);
55432d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org
555d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // Enter exit frame.
55683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  // stack_space - extra stack space, used for alignment before call to C.
55783aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  void EnterExitFrame(bool save_doubles, int stack_space = 0);
558236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org
559236ad9617a7359a463144a6ebeb5431a70f769cfager@chromium.org  // Leave the current exit frame. Expects the return value in r0.
56049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // Expect the number of values, pushed prior to the exit frame, to
56149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // remove in a register (or no_reg, if there is nothing to remove).
562528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void LeaveExitFrame(bool save_doubles,
563528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                      Register argument_count,
564528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                      bool restore_context);
56543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
566c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  // Get the actual activation frame alignment for target environment.
567c9c80823e038328f2e1060d7feef0762a50adf06ricow@chromium.org  static int ActivationFrameAlignment();
56843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
569ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org  void LoadContext(Register dst, int context_chain_length);
570ac6aa175ab59d65cfb7a88dbb621e1d7f1a80b8fsgjesse@chromium.org
5711145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  // Conditionally load the cached Array transitioned map of type
57246839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // transitioned_kind from the native context if the map in register
57346839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  // map_in_out is the cached Array map in the native context of
5741145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  // expected_kind.
5751145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org  void LoadTransitionedArrayMapConditional(
5761145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      ElementsKind expected_kind,
5771145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      ElementsKind transitioned_kind,
5781145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      Register map_in_out,
5791145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      Register scratch,
5801145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org      Label* no_map_match);
5811145ef852a4e230e1f642eecd8de155f2b26bc53jkummerow@chromium.org
582beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  void LoadGlobalFunction(int index, Register function);
583beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
584beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // Load the initial map from the global function. The registers
585beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // function and map can be the same, function is then overwritten.
586beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  void LoadGlobalFunctionInitialMap(Register function,
587beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org                                    Register map,
588beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org                                    Register scratch);
589beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
590f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  void InitializeRootRegister() {
591f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    ExternalReference roots_array_start =
592f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com        ExternalReference::roots_array_start(isolate());
593f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com    mov(kRootRegister, Operand(roots_array_start));
594f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  }
595f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
59643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
597769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  // JavaScript invokes
598769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com
599769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  // Invoke the JavaScript function code by either calling or jumping.
600769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  void InvokeCode(Register code,
601769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com                  const ParameterCount& expected,
602769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com                  const ParameterCount& actual,
603c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                  InvokeFlag flag,
604e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                  const CallWrapper& call_wrapper);
605769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com
606769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  // Invoke the JavaScript function in the given register. Changes the
607769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  // current context to the context in the function before invoking.
608769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  void InvokeFunction(Register function,
609769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com                      const ParameterCount& actual,
610c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                      InvokeFlag flag,
611e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                      const CallWrapper& call_wrapper);
612769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com
6138a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org  void InvokeFunction(Register function,
6148a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                      const ParameterCount& expected,
6158a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                      const ParameterCount& actual,
6168a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org                      InvokeFlag flag,
617e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                      const CallWrapper& call_wrapper);
6188a58f6420f995bb19fff9babb261458d49d90cb1machenbach@chromium.org
619c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  void InvokeFunction(Handle<JSFunction> function,
62032d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org                      const ParameterCount& expected,
6215c838251403b0be9a882540f1922577abba4c872ager@chromium.org                      const ParameterCount& actual,
622d2be901879306d8ff27e78e37783028d581d46fcricow@chromium.org                      InvokeFlag flag,
623e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                      const CallWrapper& call_wrapper);
6245c838251403b0be9a882540f1922577abba4c872ager@chromium.org
625023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  void IsObjectJSObjectType(Register heap_object,
626023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org                            Register map,
627023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org                            Register scratch,
628023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org                            Label* fail);
629023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
630023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  void IsInstanceJSObjectType(Register map,
631023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org                              Register scratch,
632023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org                              Label* fail);
633023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org
634023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org  void IsObjectJSStringType(Register object,
635023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org                            Register scratch,
636023421e6892b2ba6dcd2bbee117e0bfb24545cf7whesse@chromium.org                            Label* fail);
637b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org
638750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  void IsObjectNameType(Register object,
639750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                        Register scratch,
640750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                        Label* fail);
641750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
642769cc962a043dd8d92cc010dd2c50bc26f652c94mads.s.ager@gmail.com  // ---------------------------------------------------------------------------
64343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Debugger Support
64443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6455c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void DebugBreak();
64643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
64743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
64843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Exception handling
64943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
65043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Push a new try handler and link into try handler chain.
65178d1ad443658709d6c27809001a0e71efd8b898fyangguo@chromium.org  void PushTryHandler(StackHandler::Kind kind, int handler_index);
65243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
65313bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Unlink the stack handler on top of the stack from the try handler chain.
65413bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  // Must preserve the result register.
65513bd294acf56c7f824d92d4941a2aeb3cec58e0ckmillikin@chromium.org  void PopTryHandler();
65643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
65765a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org  // Passes thrown value to the handler of top of the try handler chain.
65849edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  void Throw(Register value);
65949edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
66049edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // Propagates an uncatchable exception to the top of the current JS stack's
66149edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  // handler chain.
66265a89c29ac6da09f5726f48f68eae9587b0e562aulan@chromium.org  void ThrowUncatchable(Register value);
66349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
66443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
66543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Inline caching support
66643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
66743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Generate code for checking access rights - used for security checks
66843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // on access to global objects across environments. The holder register
66943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // is left untouched, whereas both scratch registers are clobbered.
6705a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org  void CheckAccessGlobalProxy(Register holder_reg,
6715a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                              Register scratch,
6725a8ca6c70c6fc9716f18f6223c98d1fef5752cf6kasperl@chromium.org                              Label* miss);
67343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
674f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  void GetNumberHash(Register t0, Register scratch);
6756db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
6766db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org  void LoadFromNumberDictionary(Label* miss,
6776db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register elements,
6786db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register key,
6796db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register result,
6806db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register t0,
6816db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register t1,
6826db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org                                Register t2);
6836db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
6846db8871df97e7137d11f956af3c772f4f8370761sgjesse@chromium.org
685beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  inline void MarkCode(NopMarkerTypes type) {
686beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    nop(type);
687beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  }
688beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
689beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // Check if the given instruction is a 'type' marker.
6902efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // i.e. check if is is a mov r<type>, r<type> (referenced as nop(type))
691beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // These instructions are generated to mark special location in the code,
692beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  // like some special IC code.
693beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  static inline bool IsMarkedCode(Instr instr, int type) {
694e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER));
695beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    return IsNop(instr, type);
696beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  }
697beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
698beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
699beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  static inline int GetCodeMarker(Instr instr) {
700beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    int dst_reg_offset = 12;
701beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    int dst_mask = 0xf << dst_reg_offset;
702beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    int src_mask = 0xf;
703beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    int dst_reg = (instr & dst_mask) >> dst_reg_offset;
704beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    int src_reg = instr & src_mask;
705beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    uint32_t non_register_mask = ~(dst_mask | src_mask);
706beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    uint32_t mov_mask = al | 13 << 21;
707beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
708beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    // Return <n> if we have a mov rn rn, else return -1.
709beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    int type = ((instr & non_register_mask) == mov_mask) &&
710beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org               (dst_reg == src_reg) &&
711beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org               (FIRST_IC_MARKER <= dst_reg) && (dst_reg < LAST_CODE_MARKER)
712beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org                   ? src_reg
713beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org                   : -1;
714e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((type == -1) ||
715beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org           ((FIRST_IC_MARKER <= type) && (type < LAST_CODE_MARKER)));
716beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org    return type;
717beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org  }
718beb2571dca14508fbbbb47a2f606327d5968ee92ager@chromium.org
71943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
72043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
72118ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // Allocation support
72218ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
7232bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // Allocate an object in new space or old pointer space. The object_size is
7242bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // specified either in bytes or in words if the allocation flag SIZE_IN_WORDS
7252bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // is passed. If the space is exhausted control continues at the gc_required
7262bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // label. The allocated object is returned in result. If the flag
7272bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // tag_allocated_object is true the result is tagged as as a heap object.
7282bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // All registers are clobbered also when control continues at the gc_required
7292bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  // label.
7302bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org  void Allocate(int object_size,
7312bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                Register result,
7322bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                Register scratch1,
7332bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                Register scratch2,
7342bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                Label* gc_required,
7352bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org                AllocationFlags flags);
7362bda543d75374afd8d7e98f56ca99a57ae1b7bd1svenpanne@chromium.org
737f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org  void Allocate(Register object_size,
738f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register result,
739f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register scratch1,
740f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Register scratch2,
741f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                Label* gc_required,
742f705b5034dc5bc422ac1019b591469a7d0534772mstarzinger@chromium.org                AllocationFlags flags);
743a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
744a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Undo allocation in new space. The object passed and objects allocated after
745a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // it will no longer be allocated. The caller must make sure that no pointers
746a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // are left to the object(s) no longer allocated as they would be invalid when
747a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // allocation is undone.
748a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  void UndoAllocationInNewSpace(Register object, Register scratch);
74918ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org
7505c838251403b0be9a882540f1922577abba4c872ager@chromium.org
7515c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void AllocateTwoByteString(Register result,
7525c838251403b0be9a882540f1922577abba4c872ager@chromium.org                             Register length,
7535c838251403b0be9a882540f1922577abba4c872ager@chromium.org                             Register scratch1,
7545c838251403b0be9a882540f1922577abba4c872ager@chromium.org                             Register scratch2,
7555c838251403b0be9a882540f1922577abba4c872ager@chromium.org                             Register scratch3,
7565c838251403b0be9a882540f1922577abba4c872ager@chromium.org                             Label* gc_required);
7572c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  void AllocateOneByteString(Register result, Register length,
7582c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                             Register scratch1, Register scratch2,
7592c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                             Register scratch3, Label* gc_required);
7605c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void AllocateTwoByteConsString(Register result,
7615c838251403b0be9a882540f1922577abba4c872ager@chromium.org                                 Register length,
7625c838251403b0be9a882540f1922577abba4c872ager@chromium.org                                 Register scratch1,
7635c838251403b0be9a882540f1922577abba4c872ager@chromium.org                                 Register scratch2,
7645c838251403b0be9a882540f1922577abba4c872ager@chromium.org                                 Label* gc_required);
7652c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  void AllocateOneByteConsString(Register result, Register length,
7662c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                 Register scratch1, Register scratch2,
7672c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                 Label* gc_required);
7681805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  void AllocateTwoByteSlicedString(Register result,
7691805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                   Register length,
7701805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                   Register scratch1,
7711805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                   Register scratch2,
7721805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org                                   Label* gc_required);
7732c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  void AllocateOneByteSlicedString(Register result, Register length,
7742c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                   Register scratch1, Register scratch2,
7752c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                   Label* gc_required);
7765c838251403b0be9a882540f1922577abba4c872ager@chromium.org
777720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  // Allocates a heap number or jumps to the gc_required label if the young
778720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  // space is full and a scavenge is needed. All registers are clobbered also
779720dc0bc17114e33b9b2177fcb6726bda9cabd62sgjesse@chromium.org  // when control continues at the gc_required label.
7805d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org  void AllocateHeapNumber(Register result,
7815d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                          Register scratch1,
7825d8f0e6e7b477f422e3064bdf0dd5f2a23f75544kmillikin@chromium.org                          Register scratch2,
7835ad5acef6bd4ebc785f946d8bcc2a88b1e031827ricow@chromium.org                          Register heap_number_map,
784c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org                          Label* gc_required,
78558a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org                          TaggingMode tagging_mode = TAG_RESULT,
78658a725587734a6889c689668fd01f0157ed749a6machenbach@chromium.org                          MutableMode mode = IMMUTABLE);
78732d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org  void AllocateHeapNumberWithValue(Register result,
78832d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org                                   DwVfpRegister value,
78932d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org                                   Register scratch1,
79032d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org                                   Register scratch2,
79132d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org                                   Register heap_number_map,
79232d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org                                   Label* gc_required);
79332d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org
794c4e51ac6d26b42753a57a4a9e4a419243b50151clrn@chromium.org  // Copies a fixed number of fields of heap objects from src to dst.
795e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  void CopyFields(Register dst,
796e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                  Register src,
797fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                  LowDwVfpRegister double_scratch,
798e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org                  int field_count);
7995c838251403b0be9a882540f1922577abba4c872ager@chromium.org
8009ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // Copies a number of bytes from src to dst. All registers are clobbered. On
8019ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // exit src and dst will point to the place just after where the last byte was
8029ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  // read or written and length will be zero.
8039ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  void CopyBytes(Register src,
8049ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org                 Register dst,
8059ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org                 Register length,
8069ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org                 Register scratch);
8079ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
808c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Initialize fields with filler values.  Fields starting at |start_offset|
809c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // not including end_offset are overwritten with the value in |filler|.  At
810c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the end the loop, |start_offset| takes the value of |end_offset|.
811c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void InitializeFieldsWithFiller(Register start_offset,
812c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  Register end_offset,
813c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                  Register filler);
814c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
81518ad94b919217ffbcd2d3159eeb5f8c588761c47ager@chromium.org  // ---------------------------------------------------------------------------
81641044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // Support functions.
81741044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org
818eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Try to get function prototype of a function and puts the value in
819eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // the result register. Checks that the function really is a
820eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // function and jumps to the miss label if the fast checks fail. The
821eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // function register will be untouched; the other registers may be
822eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // clobbered.
823eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void TryGetFunctionPrototype(Register function,
824eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org                               Register result,
825eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org                               Register scratch,
826394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                               Label* miss,
827394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                               bool miss_on_bound_function = false);
828eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
829eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // Compare object type for heap object.  heap_object contains a non-Smi
830eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // whose object type should be compared with the given type.  This both
831eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // sets the flags and leaves the object type in the type_reg register.
832eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // It leaves the map in the map register (unless the type_reg and map register
833eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // are the same register).  It leaves the heap object in the heap_object
834eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  // register unless the heap_object register is the same register as one of the
835a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // other registers.
83637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  // Type_reg can be no_reg. In that case ip is used.
837eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org  void CompareObjectType(Register heap_object,
838eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org                         Register map,
839eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org                         Register type_reg,
840eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org                         InstanceType type);
841eadaf2282ee421d7a63a21d71369b029105341ccager@chromium.org
84237be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  // Compare object type for heap object. Branch to false_label if type
84337be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  // is lower than min_type or greater than max_type.
84437be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  // Load map into the register map.
84537be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org  void CheckObjectTypeRange(Register heap_object,
84637be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                            Register map,
84737be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                            InstanceType min_type,
84837be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                            InstanceType max_type,
84937be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org                            Label* false_label);
85037be408adf363bbe682921a4a690752fa0ec33femachenbach@chromium.org
851a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // Compare instance type in a map.  map contains a valid map object whose
852a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  // object type should be compared with the given type.  This both
85334e60787ea1e76f3ee49e859f71f036170c21f0elrn@chromium.org  // sets the flags and leaves the object type in the type_reg register.
854a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org  void CompareInstanceType(Register map,
855a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org                           Register type_reg,
856a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org                           InstanceType type);
857a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org
8585c838251403b0be9a882540f1922577abba4c872ager@chromium.org
859d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  // Check if a map for a JSObject indicates that the object has fast elements.
860d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  // Jump to the specified label if it does not.
861d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com  void CheckFastElements(Register map,
862d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                         Register scratch,
863d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com                         Label* fail);
864d6076d96a1411932548838e5960b594564264010erik.corry@gmail.com
865c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if a map for a JSObject indicates that the object can have both smi
866c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // and HeapObject elements.  Jump to the specified label if it does not.
867c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void CheckFastObjectElements(Register map,
868c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                               Register scratch,
869c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                               Label* fail);
870c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
871c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Check if a map for a JSObject indicates that the object has fast smi only
872c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // elements.  Jump to the specified label if it does not.
873830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org  void CheckFastSmiElements(Register map,
874830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                            Register scratch,
875830d30c478be03b0ac560f4002833ab141e41effsvenpanne@chromium.org                            Label* fail);
876c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
877a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  // Check to see if maybe_number can be stored as a double in
878a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  // FastDoubleElements. If it can, store it at the index specified by key in
87932d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // the FastDoubleElements array elements. Otherwise jump to fail.
880a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org  void StoreNumberToDoubleElements(Register value_reg,
881a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org                                   Register key_reg,
882a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org                                   Register elements_reg,
883a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org                                   Register scratch1,
884fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                                   LowDwVfpRegister double_scratch,
885fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                                   Label* fail,
886fb37721ea34922d8758d5cb26ae465aaf241e6b6yangguo@chromium.org                                   int elements_offset = 0);
887a8bb4d938869bdcdf759625ee868775ff24826d9svenpanne@chromium.org
888f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Compare an object's map with the specified map and its transitioned
889f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // elements maps if mode is ALLOW_ELEMENT_TRANSITION_MAPS. Condition flags are
890f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // set with result of map compare. If multiple map compares are required, the
891f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // compare sequences branches to early_success.
892f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  void CompareMap(Register obj,
893f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                  Register scratch,
894f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com                  Handle<Map> map,
895a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                  Label* early_success);
896f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com
8977028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // As above, but the map of the object is already loaded into the register
8987028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  // which is preserved by the code generated.
8997028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  void CompareMap(Register obj_map,
9007028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org                  Handle<Map> map,
901a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                  Label* early_success);
9027028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org
903f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // Check if the map of an object is equal to a specified map and branch to
904f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // label if not. Skip the smi check if not required (object is known to be a
905f2038fb01417bcf7698b87a5dfaa4a861539618aerik.corry@gmail.com  // heap object). If mode is ALLOW_ELEMENT_TRANSITION_MAPS, then also match
9062efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // against maps that are ElementsKind transition maps of the specified map.
9075c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void CheckMap(Register obj,
9085c838251403b0be9a882540f1922577abba4c872ager@chromium.org                Register scratch,
9095c838251403b0be9a882540f1922577abba4c872ager@chromium.org                Handle<Map> map,
9105c838251403b0be9a882540f1922577abba4c872ager@chromium.org                Label* fail,
911a53e8e03bcb23716d1025de362626f90f00da892svenpanne@chromium.org                SmiCheckType smi_check_type);
9125c838251403b0be9a882540f1922577abba4c872ager@chromium.org
913ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
9142cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org  void CheckMap(Register obj,
9152cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org                Register scratch,
9162cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org                Heap::RootListIndex index,
9172cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org                Label* fail,
918c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org                SmiCheckType smi_check_type);
9192cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
9202cc82ae439960d1adaf4374e093730dc23945d59ager@chromium.org
921ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // Check if the map of an object is equal to a specified map and branch to a
922ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // specified target if equal. Skip the smi check if not required (object is
923ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  // known to be a heap object)
924ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org  void DispatchMap(Register obj,
925ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                   Register scratch,
926ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                   Handle<Map> map,
927ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                   Handle<Code> success,
928ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org                   SmiCheckType smi_check_type);
929ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
930ea91cc579ade536e3a08498a8157921dd4f533d1ager@chromium.org
9318f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // Compare the object in a register to a value from the root list.
9328f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  // Uses the ip register as scratch.
9338f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void CompareRoot(Register obj, Heap::RootListIndex index);
9348f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
9358f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
9365c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Load and check the instance type of an object for being a string.
9375c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Loads the type into the second argument register.
938e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Returns a condition that will be enabled if the object was a string
939e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // and the passed-in condition passed. If the passed-in condition failed
940e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // then flags remain unchanged.
9415c838251403b0be9a882540f1922577abba4c872ager@chromium.org  Condition IsObjectStringType(Register obj,
942e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                               Register type,
943e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org                               Condition cond = al) {
944e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    ldr(type, FieldMemOperand(obj, HeapObject::kMapOffset), cond);
945e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    ldrb(type, FieldMemOperand(type, Map::kInstanceTypeOffset), cond);
946e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org    tst(type, Operand(kIsNotStringMask), cond);
947e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK_EQ(0, kStringTag);
9485c838251403b0be9a882540f1922577abba4c872ager@chromium.org    return eq;
9495c838251403b0be9a882540f1922577abba4c872ager@chromium.org  }
9505c838251403b0be9a882540f1922577abba4c872ager@chromium.org
9515c838251403b0be9a882540f1922577abba4c872ager@chromium.org
952d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // Picks out an array index from the hash field.
953d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  // Register use:
954d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  //   hash - holds the index's hash. Clobbered.
955d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  //   index - holds the overwritten index on exit.
956d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  void IndexFromHash(Register hash, Register index);
957d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
9585c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Get the number of least significant bits from a register
9595c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void GetLeastBitsFromSmi(Register dst, Register src, int num_least_bits);
960496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  void GetLeastBitsFromInt32(Register dst, Register src, int mun_least_bits);
9615c838251403b0be9a882540f1922577abba4c872ager@chromium.org
962bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  // Load the value of a smi object into a double register.
963bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  // The register value must be between d0 and d15.
964fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  void SmiToDouble(LowDwVfpRegister value, Register smi);
96532d961d4454609ab4251a760fc46b19f661da90clrn@chromium.org
966750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Check if a double can be exactly represented as a signed 32-bit integer.
967750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Z flag set to one if true.
968750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  void TestDoubleIsInt32(DwVfpRegister double_input,
969fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                         LowDwVfpRegister double_scratch);
970750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
971750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Try to convert a double to a signed 32-bit integer.
972750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Z flag set to one and result assigned if the conversion is exact.
973750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  void TryDoubleToInt32Exact(Register result,
974750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                             DwVfpRegister double_input,
975fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                             LowDwVfpRegister double_scratch);
976750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
977750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Floor a double and writes the value to the result register.
978750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Go to exact if the conversion is exact (to be able to test -0),
979750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // fall through calling code if an overflow occurred, else go to done.
980fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org  // In return, input_high is loaded with high bits of input.
981750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  void TryInt32Floor(Register result,
982750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                     DwVfpRegister double_input,
983750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                     Register input_high,
984fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                     LowDwVfpRegister double_scratch,
985750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                     Label* done,
986750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                     Label* exact);
9879ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org
988badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  // Performs a truncating conversion of a floating point number as used by
9891e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // the JS bitwise operations. See ECMA-262 9.5: ToInt32. Goes to 'done' if it
9901e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // succeeds, otherwise falls through if result is saturated. On return
9911e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // 'result' either holds answer, or is clobbered on fall through.
9921e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  //
9931e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // Only public for the test code in test-code-stubs-arm.cc.
9941e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  void TryInlineTruncateDoubleToI(Register result,
9951e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                                  DwVfpRegister input,
9961e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                                  Label* done);
9971e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
9981e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // Performs a truncating conversion of a floating point number as used by
999badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org  // the JS bitwise operations. See ECMA-262 9.5: ToInt32.
10001e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // Exits with 'result' holding the answer.
10011e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  void TruncateDoubleToI(Register result, DwVfpRegister double_input);
10021e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
10031e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // Performs a truncating conversion of a heap number as used by
10041e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // the JS bitwise operations. See ECMA-262 9.5: ToInt32. 'result' and 'input'
10051e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // must be different registers.  Exits with 'result' holding the answer.
10061e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  void TruncateHeapNumberToI(Register result, Register object);
10071e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org
10081e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // Converts the smi or heap number in object to an int32 using the rules
10091e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // for ToInt32 as described in ECMAScript 9.5.: the value is truncated
10101e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // and brought into the range -2^31 .. +2^31 - 1. 'result' and 'input' must be
10111e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  // different registers.
10121e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  void TruncateNumberToI(Register object,
10131e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                         Register result,
10141e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                         Register heap_number_map,
10151e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                         Register scratch1,
10161e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org                         Label* not_int32);
1017badaffc570baec00166b0ad3bdc96995751a7e13ricow@chromium.org
1018003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Check whether d16-d31 are available on the CPU. The result is given by the
1019003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  // Z condition flag: Z==0 if d16-d31 available, Z==1 otherwise.
1020003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org  void CheckFor32DRegs(Register scratch);
1021003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
102277ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  // Does a runtime check for 16/32 FP registers. Either way, pushes 32 double
102377ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  // values to location, saving [d0..(d15|d31)].
102477ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  void SaveFPRegs(Register location, Register scratch);
102577ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org
102677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  // Does a runtime check for 16/32 FP registers. Either way, pops 32 double
102777ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  // values to location, restoring [d0..(d15|d31)].
102877ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org  void RestoreFPRegs(Register location, Register scratch);
1029003650ee766f5e92756d470a37973fd371757485yangguo@chromium.org
103041044eb0969b0d7d5c041a077519a36efa6aff27kasperl@chromium.org  // ---------------------------------------------------------------------------
103143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Runtime calls
103243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
103343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Call a code stub.
10344cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org  void CallStub(CodeStub* stub,
10354cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org                TypeFeedbackId ast_id = TypeFeedbackId::None(),
10364cd70b470729dd5850dd4120a350f01363d16837yangguo@chromium.org                Condition cond = al);
103743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10385c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Call a code stub.
10395c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void TailCallStub(CodeStub* stub, Condition cond = al);
10405c838251403b0be9a882540f1922577abba4c872ager@chromium.org
104143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Call a runtime routine.
1042fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  void CallRuntime(const Runtime::Function* f,
1043fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                   int num_arguments,
1044fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org                   SaveFPRegsMode save_doubles = kDontSaveFPRegs);
1045fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  void CallRuntimeSaveDoubles(Runtime::FunctionId id) {
1046fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    const Runtime::Function* function = Runtime::FunctionForId(id);
1047fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org    CallRuntime(function, function->nargs, kSaveFPRegs);
1048fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  }
104943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
105043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Convenience function: Same as above, but takes the fid instead.
1051f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org  void CallRuntime(Runtime::FunctionId id,
1052f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                   int num_arguments,
1053f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org                   SaveFPRegsMode save_doubles = kDontSaveFPRegs) {
1054f9841897146bc10dbb3c45f0632bb79254602c75machenbach@chromium.org    CallRuntime(Runtime::FunctionForId(id), num_arguments, save_doubles);
1055fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  }
105643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10575c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Convenience function: call an external reference.
10585c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void CallExternalReference(const ExternalReference& ext,
10595c838251403b0be9a882540f1922577abba4c872ager@chromium.org                             int num_arguments);
10605c838251403b0be9a882540f1922577abba4c872ager@chromium.org
106143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Tail call of a runtime routine (jump).
1062ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Like JumpToExternalReference, but also takes care of passing the number
106331e7138e1a05e29ceefa8919ae12cb621a48ca7fmads.s.ager  // of parameters.
1064ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void TailCallExternalReference(const ExternalReference& ext,
1065ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                 int num_arguments,
1066ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org                                 int result_size);
1067ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
1068ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // Convenience function: tail call a runtime routine (jump).
1069ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void TailCallRuntime(Runtime::FunctionId fid,
1070a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org                       int num_arguments,
1071a1645e29968e70a41226edda2c49788fcea48b74ager@chromium.org                       int result_size);
107243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
10738e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  int CalculateStackPassedWords(int num_reg_arguments,
10748e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                                int num_double_arguments);
10758e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1076357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // Before calling a C-function from generated code, align arguments on stack.
1077357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // After aligning the frame, non-register arguments must be stored in
1078357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // sp[0], sp[4], etc., not pushed. The argument count assumes all arguments
10798e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // are word sized. If double arguments are used, this function assumes that
10808e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // all double arguments are stored before core registers; otherwise the
10818e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // correct alignment of the double values is not guaranteed.
1082357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // Some compilers/platforms require the stack to be aligned when calling
1083357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // C++ code.
1084357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // Needs a scratch register to do some arithmetic. This register will be
1085357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // trashed.
10868e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  void PrepareCallCFunction(int num_reg_arguments,
10878e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                            int num_double_registers,
10888e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                            Register scratch);
10898e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  void PrepareCallCFunction(int num_reg_arguments,
10908e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                            Register scratch);
10918e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
10928e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // There are two ways of passing double arguments on ARM, depending on
10938e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // whether soft or hard floating point ABI is used. These functions
10948e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // abstract parameter passing for the three different ways we call
10958e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // C functions from generated code.
10964ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  void MovToFloatParameter(DwVfpRegister src);
10974ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  void MovToFloatParameters(DwVfpRegister src1, DwVfpRegister src2);
10984ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  void MovToFloatResult(DwVfpRegister src);
1099357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
1100357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // Calls a C function and cleans up the space for arguments allocated
1101357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // by PrepareCallCFunction. The called function is not allowed to trigger a
1102357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // garbage collection, since that might move the code and invalidate the
1103357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // return address (unless this is somehow accounted for by the called
1104357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  // function).
1105357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org  void CallCFunction(ExternalReference function, int num_arguments);
1106c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void CallCFunction(Register function, int num_arguments);
11078e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  void CallCFunction(ExternalReference function,
11088e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                     int num_reg_arguments,
11098e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                     int num_double_arguments);
1110c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void CallCFunction(Register function,
11118e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                     int num_reg_arguments,
11128e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                     int num_double_arguments);
1113357bf65ed5309ac3a2c4bf20b6ce7770488787c2ager@chromium.org
11144ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  void MovFromFloatParameter(DwVfpRegister dst);
11154ddd2f1981d343a2efe6609a3e0ce6b9c80b6ed9machenbach@chromium.org  void MovFromFloatResult(DwVfpRegister dst);
11163a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1117c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // Calls an API function.  Allocates HandleScope, extracts returned value
1118c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // from handle and propagates exceptions.  Restores context.  stack_space
11192efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org  // - space to be unwound on exit (includes the call JS arguments space and
1120c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  // the additional space allocated for the fast call).
1121e014e5bf9ccd6a759add3b35ba610f3a0c752a90machenbach@chromium.org  void CallApiFunctionAndReturn(Register function_address,
1122b752d4061aaeb7d6a6ec368607871789d54b0207dslomov@chromium.org                                ExternalReference thunk_ref,
1123bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org                                int stack_space,
1124528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                MemOperand return_value_operand,
1125528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                                MemOperand* context_restore_operand);
112683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
1127c514574143c1bf74d4fb6e7dccb175fe9ff2f5d3sgjesse@chromium.org  // Jump to a runtime routine.
1128ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  void JumpToExternalReference(const ExternalReference& builtin);
112943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
113043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Invoke specified builtin JavaScript function. Adds an entry to
113143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // the unresolved list if the name does not resolve.
1132c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  void InvokeBuiltin(Builtins::JavaScript id,
11338e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                     InvokeFlag flag,
1134fb144a0716afe7ab8bf245f2391a9e53b3db3c89fschneider@chromium.org                     const CallWrapper& call_wrapper = NullCallWrapper());
1135b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org
1136b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  // Store the code object for the given builtin in the target register and
1137b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  // setup the function in r1.
1138b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  void GetBuiltinEntry(Register target, Builtins::JavaScript id);
113943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1140145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  // Store the function for the given builtin in the target register.
1141145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com  void GetBuiltinFunction(Register target, Builtins::JavaScript id);
1142145eff58d4f6ac0dcc53abb556dbf3cac6c3280aerik.corry@gmail.com
1143c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Handle<Object> CodeObject() {
1144e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(!code_object_.is_null());
1145c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org    return code_object_;
1146c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  }
1147061ef74c9b8acd038edf4b4355c50d097c8a9683kasperl@chromium.org
114843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1149763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  // Emit code for a truncating division by a constant. The dividend register is
1150bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org  // unchanged and ip gets clobbered. Dividend and result must be different.
1151763da4c1a1bd42dfafe0844b4c18f4882cc66352machenbach@chromium.org  void TruncatingDiv(Register result, Register dividend, int32_t divisor);
1152bcc36723a2ace28fa3b0d7dd0d1de926d313fff9machenbach@chromium.org
115343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // ---------------------------------------------------------------------------
1154a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // StatsCounter support
1155a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1156a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void SetCounter(StatsCounter* counter, int value,
1157a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                  Register scratch1, Register scratch2);
1158a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void IncrementCounter(StatsCounter* counter, int value,
1159a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                        Register scratch1, Register scratch2);
1160a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  void DecrementCounter(StatsCounter* counter, int value,
1161a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org                        Register scratch1, Register scratch2);
1162a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1163a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org
1164a74f0daeb278665869b4b6a3bc2739e88fed93b1ager@chromium.org  // ---------------------------------------------------------------------------
116543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Debugging
116643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1167378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Calls Abort(msg) if the condition cond is not satisfied.
116843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Use --debug_code to enable.
1169594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Assert(Condition cond, BailoutReason reason);
11700b9f850f0e9dc624b9e0c5254393112ecc7f8bc9ricow@chromium.org  void AssertFastElements(Register elements);
117143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Like Assert(), but always enabled.
1173594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Check(Condition cond, BailoutReason reason);
117443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Print a message to stdout and abort execution.
1176594006017e46d82ed7146611dc12c20e3c509c7ddanno@chromium.org  void Abort(BailoutReason msg);
117743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
117843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  // Verify restrictions about code generated in stubs.
117943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  void set_generating_stub(bool value) { generating_stub_ = value; }
118043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  bool generating_stub() { return generating_stub_; }
1181c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void set_has_frame(bool value) { has_frame_ = value; }
1182c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool has_frame() { return has_frame_; }
1183c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  inline bool AllowThisStubCall(CodeStub* stub);
118443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
11858e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  // EABI variant for double arguments in use.
11868e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  bool use_eabi_hardfloat() {
1187e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#ifdef __arm__
11885de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org    return base::OS::ArmUsingHardFloat();
1189e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org#elif USE_EABI_HARDFLOAT
11908e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    return true;
11918e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org#else
11928e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org    return false;
11938e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org#endif
11948e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org  }
11958e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org
1196b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // ---------------------------------------------------------------------------
119731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  // Number utilities
119831b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
119931b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  // Check whether the value of reg is a power of two and not zero. If not
120031b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  // control continues at the label not_power_of_two. If reg is a power of two
120131b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  // the register scratch contains the value of (reg - 1) when control falls
120231b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  // through.
120331b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  void JumpIfNotPowerOfTwoOrZero(Register reg,
120431b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org                                 Register scratch,
120531b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org                                 Label* not_power_of_two_or_zero);
1206ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Check whether the value of reg is a power of two and not zero.
1207ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Control falls through if it is, with scratch containing the mask
1208ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // value (reg - 1).
1209ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // Otherwise control jumps to the 'zero_and_neg' label if the value of reg is
1210ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // zero or negative, or jumps to the 'not_power_of_two' label if the value is
1211ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  // strictly positive but not a power of two.
1212ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void JumpIfNotPowerOfTwoOrZeroAndNeg(Register reg,
1213ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                       Register scratch,
1214ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                       Label* zero_and_neg,
1215ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org                                       Label* not_power_of_two);
121631b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org
121731b1277ec3b8cd17acb01c66d85a456159072157kmillikin@chromium.org  // ---------------------------------------------------------------------------
12185c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Smi utilities
12195c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1220a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  void SmiTag(Register reg, SBit s = LeaveCC) {
1221a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org    add(reg, reg, Operand(reg), s);
1222a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
1223378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  void SmiTag(Register dst, Register src, SBit s = LeaveCC) {
1224378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    add(dst, src, Operand(src), s);
1225378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
1226a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1227c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // Try to convert int32 to smi. If the value is to large, preserve
1228c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // the original value and jump to not_a_smi. Destroys scratch and
1229c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  // sets flags.
1230bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  void TrySmiTag(Register reg, Label* not_a_smi) {
1231bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    TrySmiTag(reg, reg, not_a_smi);
1232bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  }
1233bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  void TrySmiTag(Register reg, Register src, Label* not_a_smi) {
1234bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    SmiTag(ip, src, SetCC);
1235c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org    b(vs, not_a_smi);
1236bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    mov(reg, ip);
1237c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org  }
1238c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org
1239bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org
12409ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  void SmiUntag(Register reg, SBit s = LeaveCC) {
1241bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    mov(reg, Operand::SmiUntag(reg), s);
1242a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org  }
12439ee27ae43ab88e9bb6417ff9e27af64e0cf13729ager@chromium.org  void SmiUntag(Register dst, Register src, SBit s = LeaveCC) {
1244bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    mov(dst, Operand::SmiUntag(src), s);
1245378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
1246a55512615f5adc085d23bc8589d155c4b579fb7bkasperl@chromium.org
1247fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Untag the source value into destination and jump if source is a smi.
1248fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Souce and destination can be the same register.
1249fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  void UntagAndJumpIfSmi(Register dst, Register src, Label* smi_case);
1250fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
1251fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Untag the source value into destination and jump if source is not a smi.
1252fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  // Souce and destination can be the same register.
1253fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org  void UntagAndJumpIfNotSmi(Register dst, Register src, Label* non_smi_case);
1254fa458e413c3e5b8d479e49258d060b7bb4567c57danno@chromium.org
1255bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  // Test if the register contains a smi (Z == 0 (eq) if true).
1256bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  inline void SmiTst(Register value) {
1257bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    tst(value, Operand(kSmiTagMask));
1258bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  }
1259bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  inline void NonNegativeSmiTst(Register value) {
1260bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org    tst(value, Operand(kSmiTagMask | kSmiSignMask));
1261bf9432e3965b385e2e8df3701b710c105f5b3eb7ulan@chromium.org  }
1262e4ac3ef2f6fa9300bc78c5a4cb7d4cb66ac6e83dmvstanton@chromium.org  // Jump if the register contains a smi.
1263378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline void JumpIfSmi(Register value, Label* smi_label) {
1264378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    tst(value, Operand(kSmiTagMask));
1265378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    b(eq, smi_label);
1266378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
1267378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // Jump if either of the registers contain a non-smi.
1268378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  inline void JumpIfNotSmi(Register value, Label* not_smi_label) {
1269378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    tst(value, Operand(kSmiTagMask));
1270378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org    b(ne, not_smi_label);
1271378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  }
12725c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Jump if either of the registers contain a non-smi.
12735c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void JumpIfNotBothSmi(Register reg1, Register reg2, Label* on_not_both_smi);
12745c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // Jump if either of the registers contain a smi.
12755c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void JumpIfEitherSmi(Register reg1, Register reg2, Label* on_either_smi);
12765c838251403b0be9a882540f1922577abba4c872ager@chromium.org
1277c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // Abort execution if argument is a smi, enabled via --debug-code.
1278c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertNotSmi(Register object);
1279c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertSmi(Register object);
1280ea4f62e1df22417fc8dc2c2425485dca98b13d07ager@chromium.org
1281750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Abort execution if argument is not a string, enabled via --debug-code.
1282c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  void AssertString(Register object);
128349edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org
1284750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Abort execution if argument is not a name, enabled via --debug-code.
1285750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  void AssertName(Register object);
1286750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org
12872904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  // Abort execution if argument is not undefined or an AllocationSite, enabled
12882904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  // via --debug-code.
12892904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  void AssertUndefinedOrAllocationSite(Register object, Register scratch);
12902904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
129132d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  // Abort execution if reg is not the root value with the given index,
1292c859c4f83f6ec3e010213dbbe447cc1f927d01c5svenpanne@chromium.org  // enabled via --debug-code.
129332d7dbafe29be06cec1edd36c31fbe2865c799f4ulan@chromium.org  void AssertIsRoot(Register reg, Heap::RootListIndex index);
129483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
12955c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // ---------------------------------------------------------------------------
1296378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // HeapNumber utilities
1297378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
1298378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  void JumpIfNotHeapNumber(Register object,
1299378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                           Register heap_number_map,
1300378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                           Register scratch,
1301378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org                           Label* on_not_heap_number);
1302378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org
1303378b34e3f8852e94739bb77a528278fe0e2bb532ager@chromium.org  // ---------------------------------------------------------------------------
1304b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // String utilities
1305b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
1306528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // Generate code to do a lookup in the number string cache. If the number in
1307528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // the register object is found in the cache the generated code falls through
1308528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // with the result in the result register. The object and the result register
1309528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // can be the same. If the number is not found in the cache the code jumps to
1310528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  // the label not_found with only the content of register object unchanged.
1311528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org  void LookupNumberStringCache(Register object,
1312528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Register result,
1313528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Register scratch1,
1314528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Register scratch2,
1315528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Register scratch3,
1316528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org                               Label* not_found);
1317528ce02b8680a3ab6d75c7079f180a4016c69b7amachenbach@chromium.org
13182c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  // Checks if both objects are sequential one-byte strings and jumps to label
1319b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // if either is not. Assumes that neither object is a smi.
13202c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  void JumpIfNonSmisNotBothSequentialOneByteStrings(Register object1,
13212c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                                    Register object2,
13222c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                                    Register scratch1,
13232c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                                    Register scratch2,
13242c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                                    Label* failure);
1325b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
13262c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  // Checks if both objects are sequential one-byte strings and jumps to label
1327b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org  // if either is not.
13282c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  void JumpIfNotBothSequentialOneByteStrings(Register first, Register second,
13292c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                             Register scratch1,
13302c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                             Register scratch2,
13312c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                             Label* not_flat_one_byte_strings);
1332b302e56e5b70c4504faa2adf4ec3efb64a9d3e38sgjesse@chromium.org
13332c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  // Checks if both instance types are sequential one-byte strings and jumps to
1334ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // label if either is not.
13352c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  void JumpIfBothInstanceTypesAreNotSequentialOneByte(
13362c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      Register first_object_instance_type, Register second_object_instance_type,
13372c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      Register scratch1, Register scratch2, Label* failure);
13382c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org
13392c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  // Check if instance type is sequential one-byte string and jump to label if
1340ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org  // it is not.
13412c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  void JumpIfInstanceTypeIsNotSequentialOneByte(Register type, Register scratch,
13422c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org                                                Label* failure);
1343ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
134406b2696801712948b665372a38f96b1f10be6997machenbach@chromium.org  void JumpIfNotUniqueNameInstanceType(Register reg, Label* not_unique_name);
1345ce5e87bd905d592a8bd612b3dedf7a994177c13aager@chromium.org
13469af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org  void EmitSeqStringSetCharCheck(Register string,
13479af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                                 Register index,
13489af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                                 Register value,
13499af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org                                 uint32_t encoding_mask);
13509af454f6b1c6a921ac79ba0b9a979c73adb2ca1emachenbach@chromium.org
13510a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // ---------------------------------------------------------------------------
13520a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // Patching helpers.
13530a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
13540a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // Get the location of a relocated constant (its address in the constant pool)
13550a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org  // from its load site.
1356d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  void GetRelocatedValueLocation(Register ldr_location, Register result,
1357d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org                                 Register scratch);
13580a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
13590a4e901cdfb5505a896d30aa8c2e04fce0fbe069vegorov@chromium.org
1360c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  void ClampUint8(Register output_reg, Register input_reg);
1361c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1362c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org  void ClampDoubleToUint8(Register result_reg,
1363a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org                          DwVfpRegister input_reg,
1364fb732b17922ea75830be4db6b80534c4827d8a55jkummerow@chromium.org                          LowDwVfpRegister double_scratch);
1365c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
1366c53e10d01c5495df3896b9d318910b58688c6929kmillikin@chromium.org
136789e18f5599cb4cd462cb1ed324addd7388fb4d60rossberg@chromium.org  void LoadInstanceDescriptors(Register map, Register descriptors);
1368355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org  void EnumLength(Register dst, Register map);
136906ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  void NumberOfOwnDescriptors(Register dst, Register map);
137006ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org
137106ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  template<typename Field>
1372011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  void DecodeField(Register dst, Register src) {
1373d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    Ubfx(dst, src, Field::kShift, Field::kSize);
1374d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  }
1375d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org
1376d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  template<typename Field>
1377d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  void DecodeField(Register reg) {
1378d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    DecodeField<Field>(reg, reg);
1379d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  }
1380d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org
1381d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  template<typename Field>
1382d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  void DecodeFieldToSmi(Register dst, Register src) {
138306ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org    static const int shift = Field::kShift;
1384d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    static const int mask = Field::kMask >> shift << kSmiTagSize;
1385d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    STATIC_ASSERT((mask & (0x80000000u >> (kSmiTagSize - 1))) == 0);
1386d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    STATIC_ASSERT(kSmiTag == 0);
1387d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    if (shift < kSmiTagSize) {
1388d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      mov(dst, Operand(src, LSL, kSmiTagSize - shift));
1389d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      and_(dst, dst, Operand(mask));
1390d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    } else if (shift > kSmiTagSize) {
1391d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      mov(dst, Operand(src, LSR, shift - kSmiTagSize));
1392011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org      and_(dst, dst, Operand(mask));
1393d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org    } else {
1394d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org      and_(dst, src, Operand(mask));
1395011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    }
1396011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  }
1397011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org
1398011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org  template<typename Field>
1399d06b9264b1c886fc80a100e9915cf8ae07fdb4e5machenbach@chromium.org  void DecodeFieldToSmi(Register reg) {
1400011a81ffd5df0e081e7c00ef430b2fec5079bf2amachenbach@chromium.org    DecodeField<Field>(reg, reg);
140106ab2ec756e44eeaf7500b9794f9d2abc79dc8cfverwaest@chromium.org  }
140240cb878ef373bea9bdf7998829891e4096751dd0danno@chromium.org
1403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Activation support.
140497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  void EnterFrame(StackFrame::Type type, bool load_constant_pool = false);
14059ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  // Returns the pc offset at which the frame ends.
14069ca3017c616a778baff6d57c68d6d4746a130036ulan@chromium.org  int LeaveFrame(StackFrame::Type type);
1407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1408be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // Expects object in r0 and returns map with validated enum cache
1409be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  // in r0.  Assumes that any other register can be used as a scratch.
1410be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org  void CheckEnumCache(Register null_value, Label* call_runtime);
1411be6bd10d8264b7a05e0a04407eb98b253bc0f152kmillikin@chromium.org
1412ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // AllocationMemento support. Arrays may have an associated
1413ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  // AllocationMemento object that can be checked for in order to pretransition
141459297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // to another type.
141559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // On entry, receiver_reg should point to the array object.
141659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org  // scratch_reg gets clobbered.
1417b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  // If allocation info is present, condition flags are set to eq.
1418ba72ec861b69b67139c93fc6dd56f4a73c9b3135jkummerow@chromium.org  void TestJSArrayForAllocationMemento(Register receiver_reg,
1419b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                       Register scratch_reg,
1420b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                       Label* no_memento_found);
1421b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org
1422b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  void JumpIfJSArrayHasAllocationMemento(Register receiver_reg,
1423b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                         Register scratch_reg,
1424b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                         Label* memento_found) {
1425b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    Label no_memento_found;
1426b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    TestJSArrayForAllocationMemento(receiver_reg, scratch_reg,
1427b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org                                    &no_memento_found);
1428b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    b(eq, memento_found);
1429b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org    bind(&no_memento_found);
1430b4968bea48ba224f54110f626278e2c04649dd5bmstarzinger@chromium.org  }
143159297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.org
1432e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  // Jumps to found label if a prototype map has dictionary elements.
1433e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org  void JumpIfDictionaryInPrototypeChain(Register object, Register scratch0,
1434e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org                                        Register scratch1, Label* found);
1435e8412be858dc48afaec4959e42c5932f71a7f29bmachenbach@chromium.org
143643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
1437ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  void CallCFunctionHelper(Register function,
14388e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                           int num_reg_arguments,
14398e8294a88dc7d58f579aee0ba08c19fc8a616e2dsgjesse@chromium.org                           int num_double_arguments);
1440ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
14415c838251403b0be9a882540f1922577abba4c872ager@chromium.org  void Jump(intptr_t target, RelocInfo::Mode rmode, Condition cond = al);
1442b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org
1443b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  // Helper functions for generating invokes.
1444b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org  void InvokePrologue(const ParameterCount& expected,
1445b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org                      const ParameterCount& actual,
1446b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org                      Handle<Code> code_constant,
1447b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org                      Register code_reg,
1448b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org                      Label* done,
14492efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org                      bool* definitely_mismatches,
1450c6c5718277d4047fad1e034396228ce15571b5a4sgjesse@chromium.org                      InvokeFlag flag,
1451e31286d471eb2e656a1809383fa16b76053dd673machenbach@chromium.org                      const CallWrapper& call_wrapper);
1452b912362e2b2e704d09faac4290e027fd744bf587kasperl@chromium.org
1453ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org  void InitializeNewString(Register string,
1454ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org                           Register length,
1455ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org                           Heap::RootListIndex map_index,
1456ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org                           Register scratch1,
1457ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org                           Register scratch2);
1458ac091b7d178f1853ede4a5cba58e767e6adf7d96ager@chromium.org
1459c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Helper for implementing JumpIfNotInNewSpace and JumpIfInNewSpace.
1460c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void InNewSpace(Register object,
1461c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  Register scratch,
1462c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  Condition cond,  // eq for new space, ne otherwise.
1463c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  Label* branch);
1464c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
1465c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // Helper for finding the mark bits for an address.  Afterwards, the
1466c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // bitmap register points at the word with the mark bits and the mask
1467c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the position of the first bit.  Leaves addr_reg unchanged.
1468c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  inline void GetMarkBits(Register addr_reg,
1469c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                          Register bitmap_reg,
1470c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                          Register mask_reg);
1471c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
147204e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // Helper for throwing exceptions.  Compute a handler address and jump to
147304e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  // it.  See the implementation for register usage.
147404e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org  void JumpToHandlerEntry();
147504e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org
14763a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // Compute memory operands for safepoint stack slots.
14773a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  static int SafepointRegisterStackIndex(int reg_code);
14783a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  MemOperand SafepointRegisterSlot(Register reg);
14793a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  MemOperand SafepointRegistersAndDoublesSlot(Register reg);
14803a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
148197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // Loads the constant pool pointer (pp) register.
148297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  void LoadConstantPoolPointerRegister();
148397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
14845c838251403b0be9a882540f1922577abba4c872ager@chromium.org  bool generating_stub_;
1485c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  bool has_frame_;
14865c838251403b0be9a882540f1922577abba4c872ager@chromium.org  // This handle will be patched with the code object on installation.
14875c838251403b0be9a882540f1922577abba4c872ager@chromium.org  Handle<Object> code_object_;
14883a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1489a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  // Needs access to SafepointRegisterStackIndex for compiled frame
14903a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  // traversal.
1491a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.org  friend class StandardFrame;
149243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
149343d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
149443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
14954af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// The code patcher is used to patch (typically) small parts of code e.g. for
14964af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// debugging and other types of instrumentation. When using the code patcher
14974af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// the exact number of bytes specified must be emitted. It is not legal to emit
14984af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// relocation information. If any of these constraints are violated it causes
14994af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org// an assertion to fail.
15004af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.orgclass CodePatcher {
15014af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org public:
15024a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  enum FlushICache {
15034a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    FLUSH,
15044a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org    DONT_FLUSH
15054a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  };
15064a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org
15074a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  CodePatcher(byte* address,
15084a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org              int instructions,
15094a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org              FlushICache flush_cache = FLUSH);
15104af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  virtual ~CodePatcher();
15114af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
15124af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Macro assembler to emit code.
15134af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  MacroAssembler* masm() { return &masm_; }
15144af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
15154af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Emit an instruction directly.
1516496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  void Emit(Instr instr);
15174af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
15184af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  // Emit an address directly.
15194af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  void Emit(Address addr);
15204af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
1521496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  // Emit the condition part of an instruction leaving the rest of the current
1522496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  // instruction unchanged.
1523496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org  void EmitCondition(Condition cond);
1524496c03a64f12710e837204e261ef155601247895sgjesse@chromium.org
15254af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org private:
15264af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  byte* address_;  // The address of the code being patched.
15274af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  int size_;  // Number of bytes of the expected patch size.
15284af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org  MacroAssembler masm_;  // Macro assembler used to generate the code.
15294a35c5a501e5b966f895ddea8e19c3ca232cb23fdslomov@chromium.org  FlushICache flush_cache_;  // Whether to flush the I cache after patching.
15304af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org};
15314af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
15324af710e493dc8583f3b7b7ce65127ad4e7c3f8a1ager@chromium.org
153397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.orgclass FrameAndConstantPoolScope {
153497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org public:
153597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  FrameAndConstantPoolScope(MacroAssembler* masm, StackFrame::Type type)
153697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      : masm_(masm),
153797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org        type_(type),
153897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org        old_has_frame_(masm->has_frame()),
153997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org        old_constant_pool_available_(masm->is_constant_pool_available())  {
1540ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    // We only want to enable constant pool access for non-manual frame scopes
1541ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    // to ensure the constant pool pointer is valid throughout the scope.
1542e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
154397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    masm->set_has_frame(true);
154497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    masm->set_constant_pool_available(true);
1545ed1a63112185152bc10fbd02418393804a5fcf04machenbach@chromium.org    masm->EnterFrame(type, !old_constant_pool_available_);
154697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
154797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
154897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  ~FrameAndConstantPoolScope() {
154997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    masm_->LeaveFrame(type_);
155097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    masm_->set_has_frame(old_has_frame_);
155197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    masm_->set_constant_pool_available(old_constant_pool_available_);
155297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
155397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
155497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // Normally we generate the leave-frame code when this object goes
155597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // out of scope.  Sometimes we may need to generate the code somewhere else
155697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // in addition.  Calling this will achieve that, but the object stays in
155797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // scope, the MacroAssembler is still marked as being in a frame scope, and
155897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  // the code will be generated again when it goes out of scope.
155997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  void GenerateLeaveFrame() {
1560e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
156197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    masm_->LeaveFrame(type_);
156297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
156397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
156497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org private:
156597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  MacroAssembler* masm_;
156697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  StackFrame::Type type_;
156797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  bool old_has_frame_;
156897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  bool old_constant_pool_available_;
156997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
157097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  DISALLOW_IMPLICIT_CONSTRUCTORS(FrameAndConstantPoolScope);
157197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org};
157297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
157397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
157497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org// Class for scoping the the unavailability of constant pool access.
157597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.orgclass ConstantPoolUnavailableScope {
157697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org public:
157797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  explicit ConstantPoolUnavailableScope(MacroAssembler* masm)
157897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org     : masm_(masm),
157997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org       old_constant_pool_available_(masm->is_constant_pool_available()) {
158097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    if (FLAG_enable_ool_constant_pool) {
158197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org      masm_->set_constant_pool_available(false);
158297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    }
158397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
158497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  ~ConstantPoolUnavailableScope() {
158597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    if (FLAG_enable_ool_constant_pool) {
158697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org     masm_->set_constant_pool_available(old_constant_pool_available_);
158797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    }
158897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  }
158997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
159097b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org private:
159197b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  MacroAssembler* masm_;
159297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  int old_constant_pool_available_;
159397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
159497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org  DISALLOW_IMPLICIT_CONSTRUCTORS(ConstantPoolUnavailableScope);
159597b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org};
159697b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
159797b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
159843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// -----------------------------------------------------------------------------
159943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen// Static helper functions.
160043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
16011b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline MemOperand ContextOperand(Register context, int index) {
16024a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com  return MemOperand(context, Context::SlotOffset(index));
16034a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
16044a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
16054a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
16061b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orginline MemOperand GlobalObjectOperand()  {
160746839fbbdee40a3d2d924e8b5b13c4139b0b24f2yangguo@chromium.org  return ContextOperand(cp, Context::GLOBAL_OBJECT_INDEX);
16084a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com}
16094a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
16104a6c3279070e8f133607a74c08d8c08ac394ab98erik.corry@gmail.com
161165dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#ifdef GENERATED_CODE_COVERAGE
161265dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#define CODE_COVERAGE_STRINGIFY(x) #x
161365dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#define CODE_COVERAGE_TOSTRING(x) CODE_COVERAGE_STRINGIFY(x)
161465dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#define __FILE_LINE__ __FILE__ ":" CODE_COVERAGE_TOSTRING(__LINE__)
161565dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#define ACCESS_MASM(masm) masm->stop(__FILE_LINE__); masm->
161665dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#else
161765dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#define ACCESS_MASM(masm) masm->
161865dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org#endif
161965dad4b091d2925543c6326db635d0f7cf9e1edcager@chromium.org
162043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
162143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
162243d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
16235ec4892aef9cca42940d7d92302abf674365f6b7ager@chromium.org#endif  // V8_ARM_MACRO_ASSEMBLER_ARM_H_
1624