1b6d052d4d08b0de341804f273713741dee560c5everwaest@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// Redistribution and use in source and binary forms, with or without
365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// modification, are permitted provided that the following conditions are
465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// met:
565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//
665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//     * Redistributions of source code must retain the above copyright
765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//       notice, this list of conditions and the following disclaimer.
865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//     * Redistributions in binary form must reproduce the above
965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//       copyright notice, this list of conditions and the following
1065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//       disclaimer in the documentation and/or other materials provided
1165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//       with the distribution.
1265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//     * Neither the name of Google Inc. nor the names of its
1365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//       contributors may be used to endorse or promote products derived
1465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//       from this software without specific prior written permission.
1565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org//
1665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
2865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#ifndef V8_ARM_CODE_STUBS_ARM_H_
2965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#define V8_ARM_CODE_STUBS_ARM_H_
3065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
3165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#include "ic-inl.h"
3265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
3365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgnamespace v8 {
3465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.orgnamespace internal {
3565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
3665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
37ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvoid ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code);
38ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
39ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
4065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// Compute a transcendental math function natively, or call the
4165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// TranscendentalCache runtime function.
42a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass TranscendentalCacheStub: public PlatformCodeStub {
4365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org public:
448f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  enum ArgumentType {
458f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    TAGGED = 0 << TranscendentalCache::kTranscendentalTypeBits,
468f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org    UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits
478f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  };
488f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
498f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  TranscendentalCacheStub(TranscendentalCache::Type type,
508f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org                          ArgumentType argument_type)
518f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org      : type_(type), argument_type_(argument_type) { }
5265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  void Generate(MacroAssembler* masm);
5365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org private:
5465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  TranscendentalCache::Type type_;
558f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  ArgumentType argument_type_;
568f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  void GenerateCallCFunction(MacroAssembler* masm, Register scratch);
578f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org
5865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  Major MajorKey() { return TranscendentalCache; }
598f806e8b8f108ca2c8899c5d31861ef1273dcd4akarlklose@chromium.org  int MinorKey() { return type_ | argument_type_; }
6065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  Runtime::FunctionId RuntimeFunction();
6165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org};
6265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
6365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
64a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass StoreBufferOverflowStub: public PlatformCodeStub {
65c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public:
66c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp)
67e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      : save_doubles_(save_fp) {}
68c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
69c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void Generate(MacroAssembler* masm);
70c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
718432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate);
72c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  virtual bool SometimesSetsUpAFrame() { return false; }
73c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
74c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private:
75c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  SaveFPRegsMode save_doubles_;
76c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
77c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Major MajorKey() { return StoreBufferOverflow; }
78c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
79c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com};
80c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
81c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
822c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgclass StringHelper : public AllStatic {
832c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org public:
842c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // Generate code for copying characters using a simple loop. This should only
852c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // be used in places where the number of characters is small and the
862c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // additional setup and checking in GenerateCopyCharactersLong adds too much
872c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // overhead. Copying of overlapping regions is not supported.
882c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // Dest register ends at the position after the last character written.
892c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  static void GenerateCopyCharacters(MacroAssembler* masm,
902c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                     Register dest,
912c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                     Register src,
922c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                     Register count,
932c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                     Register scratch,
942c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                     bool ascii);
952c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
962c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // Generate code for copying a large number of characters. This function
972c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // is allowed to spend extra time setting up conditions to make copying
982c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // faster. Copying of overlapping regions is not supported.
992c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // Dest register ends at the position after the last character written.
1002c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  static void GenerateCopyCharactersLong(MacroAssembler* masm,
1012c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register dest,
1022c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register src,
1032c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register count,
1042c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register scratch1,
1052c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register scratch2,
1062c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register scratch3,
1072c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register scratch4,
1082c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         int flags);
1092c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1102c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1114a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // Probe the string table for a two character string. If the string is
1122c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // not found by probing a jump to the label not_found is performed. This jump
1134a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  // does not guarantee that the string is not in the string table. If the
1142c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // string is found the code falls through with the string in register r0.
1152c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // Contents of both c1 and c2 registers are modified. At the exit c1 is
1162c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // guaranteed to contain halfword with low and high bytes equal to
1172c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // initial contents of c1 and c2 respectively.
1184a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  static void GenerateTwoCharacterStringTableProbe(MacroAssembler* masm,
1192c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Register c1,
1202c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Register c2,
1212c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Register scratch1,
1222c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Register scratch2,
1232c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Register scratch3,
1242c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Register scratch4,
1252c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Register scratch5,
1262c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Label* not_found);
1272c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1282c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // Generate string hash.
1292c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  static void GenerateHashInit(MacroAssembler* masm,
1302c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                               Register hash,
1312c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                               Register character);
1322c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1332c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  static void GenerateHashAddCharacter(MacroAssembler* masm,
1342c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                       Register hash,
1352c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                       Register character);
1362c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1372c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  static void GenerateHashGetHash(MacroAssembler* masm,
1382c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                  Register hash);
1392c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1402c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org private:
1412c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
1422c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org};
1432c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1442c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
145a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass StringAddStub: public PlatformCodeStub {
14665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org public:
1473a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  explicit StringAddStub(StringAddFlags flags) : flags_(flags) {}
14865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
14965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org private:
15065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  Major MajorKey() { return StringAdd; }
1513a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  int MinorKey() { return flags_; }
15265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
15365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  void Generate(MacroAssembler* masm);
15465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
1553a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  void GenerateConvertArgument(MacroAssembler* masm,
1563a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                               int stack_offset,
1573a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                               Register arg,
1583a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                               Register scratch1,
1593a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                               Register scratch2,
1603a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                               Register scratch3,
1613a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                               Register scratch4,
1623a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org                               Label* slow);
1633a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org
1644e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  void GenerateRegisterArgsPush(MacroAssembler* masm);
1654e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  void GenerateRegisterArgsPop(MacroAssembler* masm);
1664e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
1673a5fd78f0ca6c2827bb05f69a373d152a9ce6ff3fschneider@chromium.org  const StringAddFlags flags_;
16865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org};
16965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
17065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
171a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass SubStringStub: public PlatformCodeStub {
17265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org public:
17365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  SubStringStub() {}
17465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
17565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org private:
17665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  Major MajorKey() { return SubString; }
17765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  int MinorKey() { return 0; }
17865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
17965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  void Generate(MacroAssembler* masm);
18065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org};
18165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
18265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
18365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
184a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass StringCompareStub: public PlatformCodeStub {
18565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org public:
18665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  StringCompareStub() { }
18765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
1881c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  // Compares two flat ASCII strings and returns result in r0.
18965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
19065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org                                              Register left,
19165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org                                              Register right,
19265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org                                              Register scratch1,
19365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org                                              Register scratch2,
19465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org                                              Register scratch3,
19565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org                                              Register scratch4);
19665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
1971c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  // Compares two flat ASCII strings for equality and returns result
1981c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  // in r0.
1991c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  static void GenerateFlatAsciiStringEquals(MacroAssembler* masm,
2001c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                            Register left,
2011c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                            Register right,
2021c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                            Register scratch1,
2031c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                            Register scratch2,
2041c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                            Register scratch3);
20565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
2061c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org private:
2071c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  virtual Major MajorKey() { return StringCompare; }
2081c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  virtual int MinorKey() { return 0; }
2091c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  virtual void Generate(MacroAssembler* masm);
2101c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
2111c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  static void GenerateAsciiCharsCompareLoop(MacroAssembler* masm,
2121c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                            Register left,
2131c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                            Register right,
2141c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                            Register length,
2151c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                            Register scratch1,
2161c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                            Register scratch2,
2171c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                            Label* chars_not_equal);
21865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org};
21965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
22065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
22165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// This stub can convert a signed int32 to a heap number (double).  It does
22265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// not work for int32s that are in Smi range!  No GC occurs during this stub
22365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org// so you don't have to set up the frame.
224a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass WriteInt32ToHeapNumberStub : public PlatformCodeStub {
22565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org public:
22665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  WriteInt32ToHeapNumberStub(Register the_int,
22765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org                             Register the_heap_number,
22865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org                             Register scratch)
22965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org      : the_int_(the_int),
23065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org        the_heap_number_(the_heap_number),
23165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org        scratch_(scratch) { }
23265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
2338432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate);
234c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
23565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org private:
23665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  Register the_int_;
23765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  Register the_heap_number_;
23865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  Register scratch_;
23965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
24065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  // Minor key encoding in 16 bits.
24165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  class IntRegisterBits: public BitField<int, 0, 4> {};
24265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  class HeapNumberRegisterBits: public BitField<int, 4, 4> {};
24365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  class ScratchRegisterBits: public BitField<int, 8, 4> {};
24465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
24565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  Major MajorKey() { return WriteInt32ToHeapNumber; }
24665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  int MinorKey() {
24765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    // Encode the parameters in a unique 16 bit value.
24865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org    return IntRegisterBits::encode(the_int_.code())
24965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org           | HeapNumberRegisterBits::encode(the_heap_number_.code())
25065fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org           | ScratchRegisterBits::encode(scratch_.code());
25165fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  }
25265fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
25365fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org  void Generate(MacroAssembler* masm);
25465fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org};
25565fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
25665fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
257a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass RecordWriteStub: public PlatformCodeStub {
258c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com public:
259c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  RecordWriteStub(Register object,
260c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  Register value,
261c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  Register address,
262c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  RememberedSetAction remembered_set_action,
263c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                  SaveFPRegsMode fp_mode)
264c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      : object_(object),
265c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        value_(value),
266c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        address_(address),
267c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        remembered_set_action_(remembered_set_action),
268c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        save_fp_regs_mode_(fp_mode),
269c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        regs_(object,   // An input reg.
270c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com              address,  // An input reg.
271c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com              value) {  // One scratch reg.
272c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
273c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
274c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  enum Mode {
275c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    STORE_BUFFER_ONLY,
276c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    INCREMENTAL,
277c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    INCREMENTAL_COMPACTION
278c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  };
279c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
280c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  virtual bool SometimesSetsUpAFrame() { return false; }
281c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
282c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  static void PatchBranchIntoNop(MacroAssembler* masm, int pos) {
283c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    masm->instr_at_put(pos, (masm->instr_at(pos) & ~B27) | (B24 | B20));
284c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(Assembler::IsTstImmediate(masm->instr_at(pos)));
285c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
286c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
287c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  static void PatchNopIntoBranch(MacroAssembler* masm, int pos) {
288c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    masm->instr_at_put(pos, (masm->instr_at(pos) & ~(B24 | B20)) | B27);
289c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(Assembler::IsBranch(masm->instr_at(pos)));
290c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
291c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
292c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  static Mode GetMode(Code* stub) {
293c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Instr first_instruction = Assembler::instr_at(stub->instruction_start());
294c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Instr second_instruction = Assembler::instr_at(stub->instruction_start() +
295c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                                   Assembler::kInstrSize);
296c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
297c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (Assembler::IsBranch(first_instruction)) {
298c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      return INCREMENTAL;
299c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
300c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
301c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(Assembler::IsTstImmediate(first_instruction));
302c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
303c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    if (Assembler::IsBranch(second_instruction)) {
304c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      return INCREMENTAL_COMPACTION;
305c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
306c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
307c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(Assembler::IsTstImmediate(second_instruction));
308c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
309c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return STORE_BUFFER_ONLY;
310c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
311c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
312c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  static void Patch(Code* stub, Mode mode) {
313c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    MacroAssembler masm(NULL,
314c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        stub->instruction_start(),
315c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                        stub->instruction_size());
316c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    switch (mode) {
317c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      case STORE_BUFFER_ONLY:
318c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        ASSERT(GetMode(stub) == INCREMENTAL ||
319c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com               GetMode(stub) == INCREMENTAL_COMPACTION);
320c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        PatchBranchIntoNop(&masm, 0);
321c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        PatchBranchIntoNop(&masm, Assembler::kInstrSize);
322c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        break;
323c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      case INCREMENTAL:
324c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        ASSERT(GetMode(stub) == STORE_BUFFER_ONLY);
325c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        PatchNopIntoBranch(&masm, 0);
326c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        break;
327c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      case INCREMENTAL_COMPACTION:
328c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        ASSERT(GetMode(stub) == STORE_BUFFER_ONLY);
329c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        PatchNopIntoBranch(&masm, Assembler::kInstrSize);
330c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        break;
331c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
332c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    ASSERT(GetMode(stub) == mode);
333c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    CPU::FlushICache(stub->instruction_start(), 2 * Assembler::kInstrSize);
334c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
335c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
336c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com private:
337c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // This is a helper class for freeing up 3 scratch registers.  The input is
338c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // two registers that must be preserved and one scratch register provided by
339c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  // the caller.
340c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  class RegisterAllocation {
341c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   public:
342c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    RegisterAllocation(Register object,
343c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       Register address,
344c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                       Register scratch0)
345c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        : object_(object),
346c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          address_(address),
347c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com          scratch0_(scratch0) {
348c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT(!AreAliased(scratch0, object, address, no_reg));
3491e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org      scratch1_ = GetRegisterThatIsNotOneOf(object_, address_, scratch0_);
350c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
351c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
352c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    void Save(MacroAssembler* masm) {
353c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      ASSERT(!AreAliased(object_, address_, scratch1_, scratch0_));
354c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // We don't have to save scratch0_ because it was given to us as
355c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      // a scratch register.
356c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      masm->push(scratch1_);
357c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
358c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
359c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    void Restore(MacroAssembler* masm) {
360c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      masm->pop(scratch1_);
361c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
362c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
363c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // If we have to call into C then we need to save and restore all caller-
364c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // saved registers that were not already preserved.  The scratch registers
365c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    // will be restored by other means so we don't bother pushing them here.
366c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) {
367c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      masm->stm(db_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit());
368c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (mode == kSaveFPRegs) {
36977ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org        masm->SaveFPRegs(sp, scratch0_);
370c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
371c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
372c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
373c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    inline void RestoreCallerSaveRegisters(MacroAssembler*masm,
374c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com                                           SaveFPRegsMode mode) {
375c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      if (mode == kSaveFPRegs) {
37677ca49ac05d25684c89442029c22f5b2bce94395ulan@chromium.org        masm->RestoreFPRegs(sp, scratch0_);
377c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      }
378c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      masm->ldm(ia_w, sp, (kCallerSaved | lr.bit()) & ~scratch1_.bit());
379c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    }
380c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
381c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    inline Register object() { return object_; }
382c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    inline Register address() { return address_; }
383c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    inline Register scratch0() { return scratch0_; }
384c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    inline Register scratch1() { return scratch1_; }
385c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
386c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com   private:
387c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register object_;
388c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register address_;
389c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register scratch0_;
390c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    Register scratch1_;
391c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
392c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    friend class RecordWriteStub;
393c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  };
394c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
395c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  enum OnNoNeedToInformIncrementalMarker {
396c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    kReturnOnNoNeedToInformIncrementalMarker,
397c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
398c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  };
399c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
400c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void Generate(MacroAssembler* masm);
401c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void GenerateIncremental(MacroAssembler* masm, Mode mode);
402c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void CheckNeedsToInformIncrementalMarker(
403c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      MacroAssembler* masm,
404c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      OnNoNeedToInformIncrementalMarker on_no_need,
405c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com      Mode mode);
406c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void InformIncrementalMarker(MacroAssembler* masm, Mode mode);
407c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
408c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Major MajorKey() { return RecordWrite; }
409c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
410c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  int MinorKey() {
411c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    return ObjectBits::encode(object_.code()) |
412c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        ValueBits::encode(value_.code()) |
413c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        AddressBits::encode(address_.code()) |
414c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        RememberedSetActionBits::encode(remembered_set_action_) |
415c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com        SaveFPRegsModeBits::encode(save_fp_regs_mode_);
416c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
417c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
418c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  void Activate(Code* code) {
419c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com    code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
420c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  }
421c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
422c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  class ObjectBits: public BitField<int, 0, 4> {};
423c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  class ValueBits: public BitField<int, 4, 4> {};
424c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  class AddressBits: public BitField<int, 8, 4> {};
425c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  class RememberedSetActionBits: public BitField<RememberedSetAction, 12, 1> {};
426c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 13, 1> {};
427c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
428c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Register object_;
429c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Register value_;
430c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Register address_;
431c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  RememberedSetAction remembered_set_action_;
432c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  SaveFPRegsMode save_fp_regs_mode_;
433c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  Label slow_;
434c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  RegisterAllocation regs_;
435c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com};
436c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
437c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
43883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// Trampoline stub to call into native code. To call safely into native code
43983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// in the presence of compacting GC (which can move code objects) we need to
44083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// keep the code which called into native pinned in the memory. Currently the
44183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// simplest approach is to generate such stub early enough so it can never be
44283aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org// moved by GC
443a6bbcc801f63c451f814d6da77a1a48fba3d36c6yangguo@chromium.orgclass DirectCEntryStub: public PlatformCodeStub {
44483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org public:
44583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  DirectCEntryStub() {}
44683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  void Generate(MacroAssembler* masm);
44749edbdf52640c88918f8e6638ab4965819eb1dfekmillikin@chromium.org  void GenerateCall(MacroAssembler* masm, Register target);
44883aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
44983aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org private:
45083aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  Major MajorKey() { return DirectCEntry; }
45183aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org  int MinorKey() { return 0; }
4524d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org
4534d3fe4e246b0312eba361689f288ddf8dd516960danno@chromium.org  bool NeedsImmovableCode() { return true; }
45483aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org};
45583aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
45683aa54905e559090bea7771b83f188762cfcf082ricow@chromium.org
457750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.orgclass NameDictionaryLookupStub: public PlatformCodeStub {
4581c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org public:
4591c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
4601c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
461750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  explicit NameDictionaryLookupStub(LookupMode mode) : mode_(mode) { }
4621c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
4631c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  void Generate(MacroAssembler* masm);
4641c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
465394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  static void GenerateNegativeLookup(MacroAssembler* masm,
466394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                     Label* miss,
467394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                     Label* done,
468394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                     Register receiver,
469394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                     Register properties,
470750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org                                     Handle<Name> name,
471394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                     Register scratch0);
472394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
4731c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  static void GeneratePositiveLookup(MacroAssembler* masm,
4741c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                     Label* miss,
4751c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                     Label* done,
4761c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                     Register elements,
4771c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                     Register name,
4781c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                     Register r0,
4791c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org                                     Register r1);
4801c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
481c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  virtual bool SometimesSetsUpAFrame() { return false; }
482c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
4831c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org private:
4841c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  static const int kInlinedProbes = 4;
4851c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  static const int kTotalProbes = 20;
4861c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
4871c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  static const int kCapacityOffset =
488750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      NameDictionary::kHeaderSize +
489750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      NameDictionary::kCapacityIndex * kPointerSize;
4901c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
4911c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  static const int kElementsStartOffset =
492750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      NameDictionary::kHeaderSize +
493750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org      NameDictionary::kElementsStartIndex * kPointerSize;
4941c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
495750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  Major MajorKey() { return NameDictionaryLookup; }
4961c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
4971c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  int MinorKey() {
4981c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org    return LookupModeBits::encode(mode_);
4991c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  }
5001c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
5011c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  class LookupModeBits: public BitField<LookupMode, 0, 1> {};
5021c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
5031c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org  LookupMode mode_;
5041c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org};
5051c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
5061c09276ce2ac5214e81ca554360b9f101187893blrn@chromium.org
50765fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org} }  // namespace v8::internal
50865fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org
50965fae84840520e9ce49a78bf542abf073b49ac3fricow@chromium.org#endif  // V8_ARM_CODE_STUBS_ARM_H_
510