~ubuntu-branches/ubuntu/precise/nodejs/precise

« back to all changes in this revision

Viewing changes to deps/v8/src/x64/macro-assembler-x64.h

  • Committer: Bazaar Package Importer
  • Author(s): Jérémy Lal
  • Date: 2010-08-20 11:49:04 UTC
  • mfrom: (7.1.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100820114904-lz22w6fkth7yh179
Tags: 0.2.0-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
47
47
// Default scratch register used by MacroAssembler (and other code that needs
48
48
// a spare register). The register isn't callee save, and not used by the
49
49
// function calling convention.
50
 
static const Register kScratchRegister = { 10 };  // r10.
51
 
static const Register kRootRegister = { 13 };     // r13
 
50
static const Register kScratchRegister = { 10 };      // r10.
 
51
static const Register kSmiConstantRegister = { 15 };  // r15 (callee save).
 
52
static const Register kRootRegister = { 13 };         // r13 (callee save).
 
53
// Value of smi in kSmiConstantRegister.
 
54
static const int kSmiConstantRegisterValue = 1;
52
55
 
53
56
// Convenience for platform-independent signatures.
54
57
typedef Operand MemOperand;
78
81
  // ---------------------------------------------------------------------------
79
82
  // GC Support
80
83
 
81
 
  // Set the remebered set bit for an address which points into an
82
 
  // object. RecordWriteHelper only works if the object is not in new
 
84
  // For page containing |object| mark region covering |addr| dirty.
 
85
  // RecordWriteHelper only works if the object is not in new
83
86
  // space.
84
87
  void RecordWriteHelper(Register object,
85
88
                         Register addr,
93
96
                  Condition cc,
94
97
                  Label* branch);
95
98
 
96
 
  // Set the remembered set bit for [object+offset].
97
 
  // object is the object being stored into, value is the object being stored.
98
 
  // If offset is zero, then the scratch register contains the array index into
99
 
  // the elements array represented as a Smi.
100
 
  // All registers are clobbered by the operation.
 
99
  // For page containing |object| mark region covering [object+offset]
 
100
  // dirty. |object| is the object being stored into, |value| is the
 
101
  // object being stored. If |offset| is zero, then the |scratch|
 
102
  // register contains the array index into the elements array
 
103
  // represented as a Smi. All registers are clobbered by the
 
104
  // operation. RecordWrite filters out smis so it does not update the
 
105
  // write barrier if the value is a smi.
101
106
  void RecordWrite(Register object,
102
107
                   int offset,
103
108
                   Register value,
104
109
                   Register scratch);
105
110
 
106
 
  // Set the remembered set bit for [object+offset].
 
111
  // For page containing |object| mark region covering [address]
 
112
  // dirty. |object| is the object being stored into, |value| is the
 
113
  // object being stored. All registers are clobbered by the
 
114
  // operation.  RecordWrite filters out smis so it does not update
 
115
  // the write barrier if the value is a smi.
 
116
  void RecordWrite(Register object,
 
117
                   Register address,
 
118
                   Register value);
 
119
 
 
120
  // For page containing |object| mark region covering [object+offset] dirty.
107
121
  // The value is known to not be a smi.
108
122
  // object is the object being stored into, value is the object being stored.
109
123
  // If offset is zero, then the scratch register contains the array index into
149
163
  // to the first argument in register rsi.
150
164
  void EnterExitFrame(ExitFrame::Mode mode, int result_size = 1);
151
165
 
 
166
  void EnterApiExitFrame(ExitFrame::Mode mode,
 
167
                         int stack_space,
 
168
                         int argc,
 
169
                         int result_size = 1);
 
170
 
152
171
  // Leave the current exit frame. Expects/provides the return value in
153
172
  // register rax:rdx (untouched) and the pointer to the first
154
173
  // argument in register rsi.
191
210
  // ---------------------------------------------------------------------------
192
211
  // Smi tagging, untagging and operations on tagged smis.
193
212
 
 
213
  void InitializeSmiConstantRegister() {
 
214
    movq(kSmiConstantRegister,
 
215
         reinterpret_cast<uint64_t>(Smi::FromInt(kSmiConstantRegisterValue)),
 
216
         RelocInfo::NONE);
 
217
  }
 
218
 
194
219
  // Conversions between tagged smi values and non-tagged integer values.
195
220
 
196
221
  // Tag an integer value. The result must be known to be a valid smi value.
203
228
  // NOTICE: Destroys the dst register even if unsuccessful!
204
229
  void Integer32ToSmi(Register dst, Register src, Label* on_overflow);
205
230
 
 
231
  // Stores an integer32 value into a memory field that already holds a smi.
 
232
  void Integer32ToSmiField(const Operand& dst, Register src);
 
233
 
206
234
  // Adds constant to src and tags the result as a smi.
207
235
  // Result must be a valid smi.
208
236
  void Integer64PlusConstantToSmi(Register dst, Register src, int constant);
210
238
  // Convert smi to 32-bit integer. I.e., not sign extended into
211
239
  // high 32 bits of destination.
212
240
  void SmiToInteger32(Register dst, Register src);
 
241
  void SmiToInteger32(Register dst, const Operand& src);
213
242
 
214
243
  // Convert smi to 64-bit integer (sign extended if necessary).
215
244
  void SmiToInteger64(Register dst, Register src);
 
245
  void SmiToInteger64(Register dst, const Operand& src);
216
246
 
217
247
  // Multiply a positive smi's integer value by a power of two.
218
248
  // Provides result as 64-bit integer value.
220
250
                                             Register src,
221
251
                                             int power);
222
252
 
 
253
  // Divide a positive smi's integer value by a power of two.
 
254
  // Provides result as 32-bit integer value.
 
255
  void PositiveSmiDivPowerOfTwoToInteger32(Register dst,
 
256
                                           Register src,
 
257
                                           int power);
 
258
 
 
259
 
223
260
  // Simple comparison of smis.
224
261
  void SmiCompare(Register dst, Register src);
225
262
  void SmiCompare(Register dst, Smi* src);
226
263
  void SmiCompare(Register dst, const Operand& src);
227
264
  void SmiCompare(const Operand& dst, Register src);
228
265
  void SmiCompare(const Operand& dst, Smi* src);
 
266
  // Compare the int32 in src register to the value of the smi stored at dst.
 
267
  void SmiCompareInteger32(const Operand& dst, Register src);
229
268
  // Sets sign and zero flags depending on value of smi in register.
230
269
  void SmiTest(Register src);
231
270
 
245
284
  Condition CheckBothPositiveSmi(Register first, Register second);
246
285
 
247
286
  // Are either value a tagged smi.
248
 
  Condition CheckEitherSmi(Register first, Register second);
 
287
  Condition CheckEitherSmi(Register first,
 
288
                           Register second,
 
289
                           Register scratch = kScratchRegister);
249
290
 
250
291
  // Is the value the minimum smi value (since we are using
251
292
  // two's complement numbers, negating the value is known to yield
444
485
 
445
486
  // Basic Smi operations.
446
487
  void Move(Register dst, Smi* source) {
447
 
    Set(dst, reinterpret_cast<int64_t>(source));
 
488
    LoadSmiConstant(dst, source);
448
489
  }
449
490
 
450
491
  void Move(const Operand& dst, Smi* source) {
451
 
    Set(dst, reinterpret_cast<int64_t>(source));
 
492
    Register constant = GetSmiConstant(source);
 
493
    movq(dst, constant);
452
494
  }
453
495
 
454
496
  void Push(Smi* smi);
532
574
                               Register map,
533
575
                               Register instance_type);
534
576
 
535
 
  // FCmp is similar to integer cmp, but requires unsigned
 
577
  // FCmp compares and pops the two values on top of the FPU stack.
 
578
  // The flag results are similar to integer cmp, but requires unsigned
536
579
  // jcc instructions (je, ja, jae, jb, jbe, je, and jz).
537
580
  void FCmp();
538
581
 
539
582
  // Abort execution if argument is not a number. Used in debug code.
540
583
  void AbortIfNotNumber(Register object);
541
584
 
 
585
  // Abort execution if argument is a smi. Used in debug code.
 
586
  void AbortIfSmi(Register object);
 
587
 
542
588
  // Abort execution if argument is not a smi. Used in debug code.
543
589
  void AbortIfNotSmi(Register object);
544
590
 
 
591
  // Abort execution if argument is not the root value with the given index.
 
592
  void AbortIfNotRootValue(Register src,
 
593
                           Heap::RootListIndex root_value_index,
 
594
                           const char* message);
 
595
 
545
596
  // ---------------------------------------------------------------------------
546
597
  // Exception handling
547
598
 
555
606
  // ---------------------------------------------------------------------------
556
607
  // Inline caching support
557
608
 
558
 
  // Generates code that verifies that the maps of objects in the
559
 
  // prototype chain of object hasn't changed since the code was
560
 
  // generated and branches to the miss label if any map has. If
561
 
  // necessary the function also generates code for security check
562
 
  // in case of global object holders. The scratch and holder
563
 
  // registers are always clobbered, but the object register is only
564
 
  // clobbered if it the same as the holder register. The function
565
 
  // returns a register containing the holder - either object_reg or
566
 
  // holder_reg.
567
 
  // The function can optionally (when save_at_depth !=
568
 
  // kInvalidProtoDepth) save the object at the given depth by moving
569
 
  // it to [rsp + kPointerSize].
570
 
  Register CheckMaps(JSObject* object, Register object_reg,
571
 
                     JSObject* holder, Register holder_reg,
572
 
                     Register scratch,
573
 
                     int save_at_depth,
574
 
                     Label* miss);
575
 
 
576
609
  // Generate code for checking access rights - used for security checks
577
610
  // on access to global objects across environments. The holder register
578
611
  // is left untouched, but the scratch register and kScratchRegister,
696
729
  // Call a code stub.
697
730
  void CallStub(CodeStub* stub);
698
731
 
 
732
  // Call a code stub and return the code object called.  Try to generate
 
733
  // the code if necessary.  Do not perform a GC but instead return a retry
 
734
  // after GC failure.
 
735
  Object* TryCallStub(CodeStub* stub);
 
736
 
699
737
  // Tail call a code stub (jump).
700
738
  void TailCallStub(CodeStub* stub);
701
739
 
 
740
  // Tail call a code stub (jump) and return the code object called.  Try to
 
741
  // generate the code if necessary.  Do not perform a GC but instead return
 
742
  // a retry after GC failure.
 
743
  Object* TryTailCallStub(CodeStub* stub);
 
744
 
702
745
  // Return from a code stub after popping its arguments.
703
746
  void StubReturn(int argc);
704
747
 
705
748
  // Call a runtime routine.
706
749
  void CallRuntime(Runtime::Function* f, int num_arguments);
707
750
 
 
751
  // Call a runtime function, returning the CodeStub object called.
 
752
  // Try to generate the stub code if necessary.  Do not perform a GC
 
753
  // but instead return a retry after GC failure.
 
754
  Object* TryCallRuntime(Runtime::Function* f, int num_arguments);
 
755
 
708
756
  // Convenience function: Same as above, but takes the fid instead.
709
757
  void CallRuntime(Runtime::FunctionId id, int num_arguments);
710
758
 
 
759
  // Convenience function: Same as above, but takes the fid instead.
 
760
  Object* TryCallRuntime(Runtime::FunctionId id, int num_arguments);
 
761
 
711
762
  // Convenience function: call an external reference.
712
763
  void CallExternalReference(const ExternalReference& ext,
713
764
                             int num_arguments);
724
775
                       int num_arguments,
725
776
                       int result_size);
726
777
 
 
778
  void PushHandleScope(Register scratch);
 
779
 
 
780
  // Pops a handle scope using the specified scratch register and
 
781
  // ensuring that saved register is left unchanged.
 
782
  void PopHandleScope(Register saved, Register scratch);
 
783
 
 
784
  // As PopHandleScope, but does not perform a GC.  Instead, returns a
 
785
  // retry after GC failure object if GC is necessary.
 
786
  Object* TryPopHandleScope(Register saved, Register scratch);
 
787
 
727
788
  // Jump to a runtime routine.
728
789
  void JumpToExternalReference(const ExternalReference& ext, int result_size);
729
790
 
789
850
 private:
790
851
  bool generating_stub_;
791
852
  bool allow_stub_calls_;
 
853
 
 
854
  // Returns a register holding the smi value. The register MUST NOT be
 
855
  // modified. It may be the "smi 1 constant" register.
 
856
  Register GetSmiConstant(Smi* value);
 
857
 
 
858
  // Moves the smi value to the destination register.
 
859
  void LoadSmiConstant(Register dst, Smi* value);
 
860
 
792
861
  // This handle will be patched with the code object on installation.
793
862
  Handle<Object> code_object_;
794
863
 
804
873
  void EnterFrame(StackFrame::Type type);
805
874
  void LeaveFrame(StackFrame::Type type);
806
875
 
 
876
  void EnterExitFramePrologue(ExitFrame::Mode mode, bool save_rax);
 
877
  void EnterExitFrameEpilogue(ExitFrame::Mode mode, int result_size, int argc);
 
878
 
807
879
  // Allocation support helpers.
808
880
  // Loads the top of new-space into the result register.
809
881
  // If flags contains RESULT_CONTAINS_TOP then result_end is valid and
817
889
  // Update allocation top with value in result_end register.
818
890
  // If scratch is valid, it contains the address of the allocation top.
819
891
  void UpdateAllocationTopHelper(Register result_end, Register scratch);
 
892
 
 
893
  // Helper for PopHandleScope.  Allowed to perform a GC and returns
 
894
  // NULL if gc_allowed.  Does not perform a GC if !gc_allowed, and
 
895
  // possibly returns a failure object indicating an allocation failure.
 
896
  Object* PopHandleScopeHelper(Register saved,
 
897
                               Register scratch,
 
898
                               bool gc_allowed);
820
899
};
821
900
 
822
901