183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org// Copyright 2011 the V8 project authors. All rights reserved.
27516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Redistribution and use in source and binary forms, with or without
37516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// modification, are permitted provided that the following conditions are
47516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// met:
57516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//
67516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//     * Redistributions of source code must retain the above copyright
77516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//       notice, this list of conditions and the following disclaimer.
87516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//     * Redistributions in binary form must reproduce the above
97516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//       copyright notice, this list of conditions and the following
107516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//       disclaimer in the documentation and/or other materials provided
117516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//       with the distribution.
127516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//     * Neither the name of Google Inc. nor the names of its
137516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//       contributors may be used to endorse or promote products derived
147516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//       from this software without specific prior written permission.
157516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org//
167516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
177516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
187516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
197516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
267516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#ifndef V8_MIPS_CODE_STUBS_ARM_H_
297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#define V8_MIPS_CODE_STUBS_ARM_H_
307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#include "ic-inl.h"
327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgnamespace v8 {
357516f05132429850aa326421ed3e25f23b4c071blrn@chromium.orgnamespace internal {
367516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
377516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
38ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.orgvoid ArrayNativeCode(MacroAssembler* masm, Label* call_generic_code);
39ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
40ca29dd85fa02449d17188f5a6ff9a7cdf2ad9680danno@chromium.org
417516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// Compute a transcendental math function natively, or call the
427516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// TranscendentalCache runtime function.
4359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgclass TranscendentalCacheStub: public PlatformCodeStub {
447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org public:
4583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  enum ArgumentType {
4683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    TAGGED = 0 << TranscendentalCache::kTranscendentalTypeBits,
4783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    UNTAGGED = 1 << TranscendentalCache::kTranscendentalTypeBits
4883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  };
4983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
5083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  TranscendentalCacheStub(TranscendentalCache::Type type,
5183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                          ArgumentType argument_type)
5283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org      : type_(type), argument_type_(argument_type) { }
537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void Generate(MacroAssembler* masm);
547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org private:
557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  TranscendentalCache::Type type_;
5683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  ArgumentType argument_type_;
5783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void GenerateCallCFunction(MacroAssembler* masm, Register scratch);
5883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Major MajorKey() { return TranscendentalCache; }
6083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  int MinorKey() { return type_ | argument_type_; }
617516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Runtime::FunctionId RuntimeFunction();
627516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org};
637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
6559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgclass StoreBufferOverflowStub: public PlatformCodeStub {
66b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org public:
67b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  explicit StoreBufferOverflowStub(SaveFPRegsMode save_fp)
68e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org      : save_doubles_(save_fp) {}
69b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
70b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void Generate(MacroAssembler* masm);
71b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
728432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate);
73b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  virtual bool SometimesSetsUpAFrame() { return false; }
74b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
75b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org private:
76b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  SaveFPRegsMode save_doubles_;
77b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
78b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  Major MajorKey() { return StoreBufferOverflow; }
79b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  int MinorKey() { return (save_doubles_ == kSaveFPRegs) ? 1 : 0; }
80b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org};
81b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
82b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
832c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.orgclass StringHelper : public AllStatic {
842c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org public:
852c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // Generate code for copying characters using a simple loop. This should only
862c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // be used in places where the number of characters is small and the
872c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // additional setup and checking in GenerateCopyCharactersLong adds too much
882c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // overhead. Copying of overlapping regions is not supported.
892c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // Dest register ends at the position after the last character written.
902c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  static void GenerateCopyCharacters(MacroAssembler* masm,
912c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                     Register dest,
922c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                     Register src,
932c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                     Register count,
942c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                     Register scratch,
952c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                     bool ascii);
962c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
972c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // Generate code for copying a large number of characters. This function
982c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // is allowed to spend extra time setting up conditions to make copying
992c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // faster. Copying of overlapping regions is not supported.
1002c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // Dest register ends at the position after the last character written.
1012c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  static void GenerateCopyCharactersLong(MacroAssembler* masm,
1022c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register dest,
1032c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register src,
1042c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register count,
1052c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register scratch1,
1062c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register scratch2,
1072c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register scratch3,
1082c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register scratch4,
1092c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         Register scratch5,
1102c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                         int flags);
1112c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1122c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
113750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // Probe the string table for a two character string. If the string is
1142c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // not found by probing a jump to the label not_found is performed. This jump
115750145ab1b720c97adf2b548cc8fbd28c8b8e06dulan@chromium.org  // does not guarantee that the string is not in the string table. If the
1162c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // string is found the code falls through with the string in register r0.
1172c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // Contents of both c1 and c2 registers are modified. At the exit c1 is
1182c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // guaranteed to contain halfword with low and high bytes equal to
1192c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // initial contents of c1 and c2 respectively.
1204a9f6553038df6b893b3d3ccae351723f4cbbae7yangguo@chromium.org  static void GenerateTwoCharacterStringTableProbe(MacroAssembler* masm,
1212c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Register c1,
1222c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Register c2,
1232c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Register scratch1,
1242c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Register scratch2,
1252c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Register scratch3,
1262c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Register scratch4,
1272c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Register scratch5,
1282c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                                   Label* not_found);
1292c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1302c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  // Generate string hash.
1312c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  static void GenerateHashInit(MacroAssembler* masm,
1322c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                               Register hash,
1332c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                               Register character);
1342c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1352c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  static void GenerateHashAddCharacter(MacroAssembler* masm,
1362c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                       Register hash,
1372c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                       Register character);
1382c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1392c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  static void GenerateHashGetHash(MacroAssembler* masm,
1402c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org                                  Register hash);
1412c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1422c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org private:
1432c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org  DISALLOW_IMPLICIT_CONSTRUCTORS(StringHelper);
1442c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org};
1452c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
1462c4567981e65b51f161283f8635e110a73629c9ddanno@chromium.org
14759297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgclass StringAddStub: public PlatformCodeStub {
1487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org public:
14983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  explicit StringAddStub(StringAddFlags flags) : flags_(flags) {}
1507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org private:
1527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Major MajorKey() { return StringAdd; }
15383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  int MinorKey() { return flags_; }
1547516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void Generate(MacroAssembler* masm);
1567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
15783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void GenerateConvertArgument(MacroAssembler* masm,
15883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               int stack_offset,
15983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Register arg,
16083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Register scratch1,
16183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Register scratch2,
16283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Register scratch3,
16383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Register scratch4,
16483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                               Label* slow);
16583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
1664e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  void GenerateRegisterArgsPush(MacroAssembler* masm);
1674e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org  void GenerateRegisterArgsPop(MacroAssembler* masm);
1684e308cf00936c6e7bead43e5141a04e37b49b9b5jkummerow@chromium.org
16983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  const StringAddFlags flags_;
1707516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org};
1717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1727516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
17359297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgclass SubStringStub: public PlatformCodeStub {
1747516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org public:
1757516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  SubStringStub() {}
1767516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1777516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org private:
1787516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Major MajorKey() { return SubString; }
1797516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int MinorKey() { return 0; }
1807516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1817516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void Generate(MacroAssembler* masm);
1827516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org};
1837516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1847516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
18559297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgclass StringCompareStub: public PlatformCodeStub {
1867516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org public:
1877516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  StringCompareStub() { }
1887516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
1897516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Compare two flat ASCII strings and returns result in v0.
1907516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  static void GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
1917516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                              Register left,
1927516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                              Register right,
1937516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                              Register scratch1,
1947516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                              Register scratch2,
1957516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                              Register scratch3,
1967516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                                              Register scratch4);
1977516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
19883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // Compares two flat ASCII strings for equality and returns result
19983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  // in v0.
20083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  static void GenerateFlatAsciiStringEquals(MacroAssembler* masm,
20183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                            Register left,
20283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                            Register right,
20383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                            Register scratch1,
20483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                            Register scratch2,
20583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                            Register scratch3);
2067516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
20783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org private:
20883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  virtual Major MajorKey() { return StringCompare; }
20983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  virtual int MinorKey() { return 0; }
21083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  virtual void Generate(MacroAssembler* masm);
21183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
21283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  static void GenerateAsciiCharsCompareLoop(MacroAssembler* masm,
21383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                            Register left,
21483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                            Register right,
21583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                            Register length,
21683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                            Register scratch1,
21783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                            Register scratch2,
21883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                            Register scratch3,
21983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                            Label* chars_not_equal);
2207516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org};
2217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
2227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
2237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// This stub can convert a signed int32 to a heap number (double).  It does
2247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// not work for int32s that are in Smi range!  No GC occurs during this stub
2257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org// so you don't have to set up the frame.
22659297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgclass WriteInt32ToHeapNumberStub : public PlatformCodeStub {
2277516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org public:
2287516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  WriteInt32ToHeapNumberStub(Register the_int,
2297516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                             Register the_heap_number,
2307516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                             Register scratch,
2317516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org                             Register scratch2)
2327516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org      : the_int_(the_int),
2337516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        the_heap_number_(the_heap_number),
2347516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org        scratch_(scratch),
235b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        sign_(scratch2) {
236b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    ASSERT(IntRegisterBits::is_valid(the_int_.code()));
237b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    ASSERT(HeapNumberRegisterBits::is_valid(the_heap_number_.code()));
238b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    ASSERT(ScratchRegisterBits::is_valid(scratch_.code()));
239b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    ASSERT(SignRegisterBits::is_valid(sign_.code()));
240b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
241b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
2428432c9102e4b2125d8eec741d35237cf23167471hpayer@chromium.org  static void GenerateFixedRegStubsAheadOfTime(Isolate* isolate);
2437516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
2447516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org private:
2457516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Register the_int_;
2467516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Register the_heap_number_;
2477516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Register scratch_;
2487516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Register sign_;
2497516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
2507516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  // Minor key encoding in 16 bits.
2517516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  class IntRegisterBits: public BitField<int, 0, 4> {};
2527516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  class HeapNumberRegisterBits: public BitField<int, 4, 4> {};
2537516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  class ScratchRegisterBits: public BitField<int, 8, 4> {};
254b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  class SignRegisterBits: public BitField<int, 12, 4> {};
2557516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
2567516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  Major MajorKey() { return WriteInt32ToHeapNumber; }
2577516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  int MinorKey() {
2587516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    // Encode the parameters in a unique 16 bit value.
2597516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org    return IntRegisterBits::encode(the_int_.code())
2607516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org           | HeapNumberRegisterBits::encode(the_heap_number_.code())
261b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org           | ScratchRegisterBits::encode(scratch_.code())
262b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org           | SignRegisterBits::encode(sign_.code());
2637516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  }
2647516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
2657516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org  void Generate(MacroAssembler* masm);
2667516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org};
2677516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
2687516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
26959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgclass RecordWriteStub: public PlatformCodeStub {
270b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org public:
271b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  RecordWriteStub(Register object,
272b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                  Register value,
273b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                  Register address,
274b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                  RememberedSetAction remembered_set_action,
275b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                  SaveFPRegsMode fp_mode)
276b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      : object_(object),
277b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        value_(value),
278b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        address_(address),
279b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        remembered_set_action_(remembered_set_action),
280b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        save_fp_regs_mode_(fp_mode),
281b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        regs_(object,   // An input reg.
282b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org              address,  // An input reg.
283b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org              value) {  // One scratch reg.
284b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
285b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
286b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  enum Mode {
287b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    STORE_BUFFER_ONLY,
288b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    INCREMENTAL,
289b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    INCREMENTAL_COMPACTION
290b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  };
291b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
292b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  virtual bool SometimesSetsUpAFrame() { return false; }
293b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
294b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  static void PatchBranchIntoNop(MacroAssembler* masm, int pos) {
295b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    const unsigned offset = masm->instr_at(pos) & kImm16Mask;
296b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    masm->instr_at_put(pos, BNE | (zero_reg.code() << kRsShift) |
297b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        (zero_reg.code() << kRtShift) | (offset & kImm16Mask));
298b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    ASSERT(Assembler::IsBne(masm->instr_at(pos)));
299b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
300b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
301b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  static void PatchNopIntoBranch(MacroAssembler* masm, int pos) {
302b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    const unsigned offset = masm->instr_at(pos) & kImm16Mask;
303b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    masm->instr_at_put(pos, BEQ | (zero_reg.code() << kRsShift) |
304b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        (zero_reg.code() << kRtShift) | (offset & kImm16Mask));
305b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    ASSERT(Assembler::IsBeq(masm->instr_at(pos)));
306b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
307b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
308b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  static Mode GetMode(Code* stub) {
309b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    Instr first_instruction = Assembler::instr_at(stub->instruction_start());
310b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    Instr second_instruction = Assembler::instr_at(stub->instruction_start() +
311b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                                                   2 * Assembler::kInstrSize);
312b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
313b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    if (Assembler::IsBeq(first_instruction)) {
314b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      return INCREMENTAL;
315b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    }
316b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
317b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    ASSERT(Assembler::IsBne(first_instruction));
318b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
319b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    if (Assembler::IsBeq(second_instruction)) {
320b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      return INCREMENTAL_COMPACTION;
321b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    }
322b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
323b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    ASSERT(Assembler::IsBne(second_instruction));
324b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
325b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    return STORE_BUFFER_ONLY;
326b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
327b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
328b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  static void Patch(Code* stub, Mode mode) {
329b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    MacroAssembler masm(NULL,
330b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                        stub->instruction_start(),
331b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                        stub->instruction_size());
332b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    switch (mode) {
333b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      case STORE_BUFFER_ONLY:
334b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        ASSERT(GetMode(stub) == INCREMENTAL ||
335b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org               GetMode(stub) == INCREMENTAL_COMPACTION);
336b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        PatchBranchIntoNop(&masm, 0);
337b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        PatchBranchIntoNop(&masm, 2 * Assembler::kInstrSize);
338b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        break;
339b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      case INCREMENTAL:
340b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        ASSERT(GetMode(stub) == STORE_BUFFER_ONLY);
341b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        PatchNopIntoBranch(&masm, 0);
342b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        break;
343b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      case INCREMENTAL_COMPACTION:
344b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        ASSERT(GetMode(stub) == STORE_BUFFER_ONLY);
345b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        PatchNopIntoBranch(&masm, 2 * Assembler::kInstrSize);
346b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        break;
347b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    }
348b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    ASSERT(GetMode(stub) == mode);
349b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    CPU::FlushICache(stub->instruction_start(), 4 * Assembler::kInstrSize);
350b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
351b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
352b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org private:
353b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // This is a helper class for freeing up 3 scratch registers.  The input is
354b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // two registers that must be preserved and one scratch register provided by
355b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  // the caller.
356b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  class RegisterAllocation {
357b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org   public:
358b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    RegisterAllocation(Register object,
359b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                       Register address,
360b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                       Register scratch0)
361b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        : object_(object),
362b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org          address_(address),
363b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org          scratch0_(scratch0) {
364b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      ASSERT(!AreAliased(scratch0, object, address, no_reg));
3658fa5bd929d2f128e3d554398bd085b3c2f98e23bjkummerow@chromium.org      scratch1_ = GetRegisterThatIsNotOneOf(object_, address_, scratch0_);
366b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    }
367b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
368b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    void Save(MacroAssembler* masm) {
369b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      ASSERT(!AreAliased(object_, address_, scratch1_, scratch0_));
370b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      // We don't have to save scratch0_ because it was given to us as
371b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      // a scratch register.
372b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      masm->push(scratch1_);
373b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    }
374b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
375b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    void Restore(MacroAssembler* masm) {
376b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      masm->pop(scratch1_);
377b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    }
378b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
379b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    // If we have to call into C then we need to save and restore all caller-
380b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    // saved registers that were not already preserved.  The scratch registers
381b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    // will be restored by other means so we don't bother pushing them here.
382b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    void SaveCallerSaveRegisters(MacroAssembler* masm, SaveFPRegsMode mode) {
383b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      masm->MultiPush((kJSCallerSaved | ra.bit()) & ~scratch1_.bit());
384b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      if (mode == kSaveFPRegs) {
385b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        masm->MultiPushFPU(kCallerSavedFPU);
386b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      }
387b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    }
388b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
389b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    inline void RestoreCallerSaveRegisters(MacroAssembler*masm,
390b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org                                           SaveFPRegsMode mode) {
391b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      if (mode == kSaveFPRegs) {
392b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        masm->MultiPopFPU(kCallerSavedFPU);
393b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      }
394b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      masm->MultiPop((kJSCallerSaved | ra.bit()) & ~scratch1_.bit());
395b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    }
396b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
397b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    inline Register object() { return object_; }
398b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    inline Register address() { return address_; }
399b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    inline Register scratch0() { return scratch0_; }
400b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    inline Register scratch1() { return scratch1_; }
401b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
402b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org   private:
403b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    Register object_;
404b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    Register address_;
405b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    Register scratch0_;
406b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    Register scratch1_;
407b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
408b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    friend class RecordWriteStub;
409b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  };
410b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
411b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  enum OnNoNeedToInformIncrementalMarker {
412b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    kReturnOnNoNeedToInformIncrementalMarker,
413b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    kUpdateRememberedSetOnNoNeedToInformIncrementalMarker
414b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  };
415b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
416b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void Generate(MacroAssembler* masm);
417b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void GenerateIncremental(MacroAssembler* masm, Mode mode);
418b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void CheckNeedsToInformIncrementalMarker(
419b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      MacroAssembler* masm,
420b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      OnNoNeedToInformIncrementalMarker on_no_need,
421b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org      Mode mode);
422b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void InformIncrementalMarker(MacroAssembler* masm, Mode mode);
423b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
424b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  Major MajorKey() { return RecordWrite; }
425b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
426b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  int MinorKey() {
427b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    return ObjectBits::encode(object_.code()) |
428b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        ValueBits::encode(value_.code()) |
429b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        AddressBits::encode(address_.code()) |
430b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        RememberedSetActionBits::encode(remembered_set_action_) |
431b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org        SaveFPRegsModeBits::encode(save_fp_regs_mode_);
432b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
433b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
434b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  void Activate(Code* code) {
435b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org    code->GetHeap()->incremental_marking()->ActivateGeneratedStub(code);
436b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  }
437b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
438b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  class ObjectBits: public BitField<int, 0, 5> {};
439b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  class ValueBits: public BitField<int, 5, 5> {};
440b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  class AddressBits: public BitField<int, 10, 5> {};
441b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  class RememberedSetActionBits: public BitField<RememberedSetAction, 15, 1> {};
442b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  class SaveFPRegsModeBits: public BitField<SaveFPRegsMode, 16, 1> {};
443b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
444b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  Register object_;
445b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  Register value_;
446b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  Register address_;
447b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  RememberedSetAction remembered_set_action_;
448b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  SaveFPRegsMode save_fp_regs_mode_;
449b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  Label slow_;
450b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org  RegisterAllocation regs_;
451b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org};
452b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
453b4b2aa69a9f12525fca190287f47a66d7bdcb3aerossberg@chromium.org
4547304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org// Trampoline stub to call into native code. To call safely into native code
4557304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org// in the presence of compacting GC (which can move code objects) we need to
4567304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org// keep the code which called into native pinned in the memory. Currently the
4577304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org// simplest approach is to generate such stub early enough so it can never be
4587304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org// moved by GC
45959297c735ad2a41156ae9c723a39ff259ad061e0jkummerow@chromium.orgclass DirectCEntryStub: public PlatformCodeStub {
4607304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org public:
4617304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  DirectCEntryStub() {}
4627304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  void Generate(MacroAssembler* masm);
4637304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  void GenerateCall(MacroAssembler* masm, Register target);
4647304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
4657304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org private:
4667304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  Major MajorKey() { return DirectCEntry; }
4677304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  int MinorKey() { return 0; }
4687304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org
4697304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org  bool NeedsImmovableCode() { return true; }
4707304bcac06a6a63b9f3dcebac2eeceada87ca146vegorov@chromium.org};
4717516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
47283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
4739faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.orgclass NameDictionaryLookupStub: public PlatformCodeStub {
47483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org public:
47583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  enum LookupMode { POSITIVE_LOOKUP, NEGATIVE_LOOKUP };
47683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
4779faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  explicit NameDictionaryLookupStub(LookupMode mode) : mode_(mode) { }
47883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
47983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  void Generate(MacroAssembler* masm);
48083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
481394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  static void GenerateNegativeLookup(MacroAssembler* masm,
482394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                     Label* miss,
483394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                     Label* done,
484394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                     Register receiver,
485394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                     Register properties,
4869faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org                                     Handle<Name> name,
487394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                     Register scratch0);
488394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
48983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  static void GeneratePositiveLookup(MacroAssembler* masm,
49083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                     Label* miss,
49183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                     Label* done,
49283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                     Register elements,
49383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                     Register name,
49483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                     Register r0,
49583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org                                     Register r1);
49683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
497c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com  virtual bool SometimesSetsUpAFrame() { return false; }
498c3b670ff19220959730d7886892bc4beb95d2ebaerik.corry@gmail.com
49983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org private:
50083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  static const int kInlinedProbes = 4;
50183a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  static const int kTotalProbes = 20;
50283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
50383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  static const int kCapacityOffset =
5049faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      NameDictionary::kHeaderSize +
5059faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      NameDictionary::kCapacityIndex * kPointerSize;
50683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
50783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  static const int kElementsStartOffset =
5089faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      NameDictionary::kHeaderSize +
5099faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org      NameDictionary::kElementsStartIndex * kPointerSize;
51083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
5119faefa4670e0c454c6e56bb87b4410d73828e84fsvenpanne@chromium.org  Major MajorKey() { return NameDictionaryLookup; }
51283a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
51383a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  int MinorKey() {
51483a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org    return LookupModeBits::encode(mode_);
51583a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  }
51683a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
51783a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  class LookupModeBits: public BitField<LookupMode, 0, 1> {};
51883a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org
51983a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org  LookupMode mode_;
52083a4728861129dc263ded92157f3e6389f851f19karlklose@chromium.org};
5217516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
5227516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
5237516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org} }  // namespace v8::internal
5247516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org
5257516f05132429850aa326421ed3e25f23b4c071blrn@chromium.org#endif  // V8_MIPS_CODE_STUBS_ARM_H_
526