Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Side by Side Diff: src/x64/macro-assembler-x64.h

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/lithium-x64.cc ('k') | src/x64/macro-assembler-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 ScaleFactor scale; 67 ScaleFactor scale;
68 }; 68 };
69 69
70 // MacroAssembler implements a collection of frequently used macros. 70 // MacroAssembler implements a collection of frequently used macros.
71 class MacroAssembler: public Assembler { 71 class MacroAssembler: public Assembler {
72 public: 72 public:
73 MacroAssembler(void* buffer, int size); 73 MacroAssembler(void* buffer, int size);
74 74
75 void LoadRoot(Register destination, Heap::RootListIndex index); 75 void LoadRoot(Register destination, Heap::RootListIndex index);
76 void CompareRoot(Register with, Heap::RootListIndex index); 76 void CompareRoot(Register with, Heap::RootListIndex index);
77 void CompareRoot(Operand with, Heap::RootListIndex index); 77 void CompareRoot(const Operand& with, Heap::RootListIndex index);
78 void PushRoot(Heap::RootListIndex index); 78 void PushRoot(Heap::RootListIndex index);
79 void StoreRoot(Register source, Heap::RootListIndex index); 79 void StoreRoot(Register source, Heap::RootListIndex index);
80 80
81 // --------------------------------------------------------------------------- 81 // ---------------------------------------------------------------------------
82 // GC Support 82 // GC Support
83 83
84 // For page containing |object| mark region covering |addr| dirty. 84 // For page containing |object| mark region covering |addr| dirty.
85 // RecordWriteHelper only works if the object is not in new 85 // RecordWriteHelper only works if the object is not in new
86 // space. 86 // space.
87 void RecordWriteHelper(Register object, 87 void RecordWriteHelper(Register object,
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); } 149 void EnterConstructFrame() { EnterFrame(StackFrame::CONSTRUCT); }
150 void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); } 150 void LeaveConstructFrame() { LeaveFrame(StackFrame::CONSTRUCT); }
151 151
152 // Enter specific kind of exit frame; either in normal or 152 // Enter specific kind of exit frame; either in normal or
153 // debug mode. Expects the number of arguments in register rax and 153 // debug mode. Expects the number of arguments in register rax and
154 // sets up the number of arguments in register rdi and the pointer 154 // sets up the number of arguments in register rdi and the pointer
155 // to the first argument in register rsi. 155 // to the first argument in register rsi.
156 // 156 //
157 // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack 157 // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack
158 // accessible via StackSpaceOperand. 158 // accessible via StackSpaceOperand.
159 void EnterExitFrame(int arg_stack_space = 0); 159 void EnterExitFrame(int arg_stack_space = 0, bool save_doubles = false);
160 160
161 // Enter specific kind of exit frame. Allocates arg_stack_space * kPointerSize 161 // Enter specific kind of exit frame. Allocates arg_stack_space * kPointerSize
162 // memory (not GCed) on the stack accessible via StackSpaceOperand. 162 // memory (not GCed) on the stack accessible via StackSpaceOperand.
163 void EnterApiExitFrame(int arg_stack_space); 163 void EnterApiExitFrame(int arg_stack_space);
164 164
165 // Leave the current exit frame. Expects/provides the return value in 165 // Leave the current exit frame. Expects/provides the return value in
166 // register rax:rdx (untouched) and the pointer to the first 166 // register rax:rdx (untouched) and the pointer to the first
167 // argument in register rsi. 167 // argument in register rsi.
168 void LeaveExitFrame(); 168 void LeaveExitFrame(bool save_doubles = false);
169 169
170 // Leave the current exit frame. Expects/provides the return value in 170 // Leave the current exit frame. Expects/provides the return value in
171 // register rax (untouched). 171 // register rax (untouched).
172 void LeaveApiExitFrame(); 172 void LeaveApiExitFrame();
173 173
174 // Push and pop the registers that can hold pointers. 174 // Push and pop the registers that can hold pointers.
175 void PushSafepointRegisters() { UNIMPLEMENTED(); } 175 void PushSafepointRegisters() { Pushad(); }
176 void PopSafepointRegisters() { UNIMPLEMENTED(); } 176 void PopSafepointRegisters() { Popad(); }
177 static int SafepointRegisterStackIndex(int reg_code) { 177 static int SafepointRegisterStackIndex(int reg_code) {
178 UNIMPLEMENTED(); 178 return kNumSafepointRegisters - 1 -
179 return 0; 179 kSafepointPushRegisterIndices[reg_code];
180 } 180 }
181 181
182
182 // --------------------------------------------------------------------------- 183 // ---------------------------------------------------------------------------
183 // JavaScript invokes 184 // JavaScript invokes
184 185
185 // Invoke the JavaScript function code by either calling or jumping. 186 // Invoke the JavaScript function code by either calling or jumping.
186 void InvokeCode(Register code, 187 void InvokeCode(Register code,
187 const ParameterCount& expected, 188 const ParameterCount& expected,
188 const ParameterCount& actual, 189 const ParameterCount& actual,
189 InvokeFlag flag); 190 InvokeFlag flag);
190 191
191 void InvokeCode(Handle<Code> code, 192 void InvokeCode(Handle<Code> code,
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
269 // Compare the int32 in src register to the value of the smi stored at dst. 270 // Compare the int32 in src register to the value of the smi stored at dst.
270 void SmiCompareInteger32(const Operand& dst, Register src); 271 void SmiCompareInteger32(const Operand& dst, Register src);
271 // Sets sign and zero flags depending on value of smi in register. 272 // Sets sign and zero flags depending on value of smi in register.
272 void SmiTest(Register src); 273 void SmiTest(Register src);
273 274
274 // Functions performing a check on a known or potential smi. Returns 275 // Functions performing a check on a known or potential smi. Returns
275 // a condition that is satisfied if the check is successful. 276 // a condition that is satisfied if the check is successful.
276 277
277 // Is the value a tagged smi. 278 // Is the value a tagged smi.
278 Condition CheckSmi(Register src); 279 Condition CheckSmi(Register src);
280 Condition CheckSmi(const Operand& src);
279 281
280 // Is the value a non-negative tagged smi. 282 // Is the value a non-negative tagged smi.
281 Condition CheckNonNegativeSmi(Register src); 283 Condition CheckNonNegativeSmi(Register src);
282 284
283 // Are both values tagged smis. 285 // Are both values tagged smis.
284 Condition CheckBothSmi(Register first, Register second); 286 Condition CheckBothSmi(Register first, Register second);
285 287
286 // Are both values non-negative tagged smis. 288 // Are both values non-negative tagged smis.
287 Condition CheckBothNonNegativeSmi(Register first, Register second); 289 Condition CheckBothNonNegativeSmi(Register first, Register second);
288 290
289 // Are either value a tagged smi. 291 // Are either value a tagged smi.
290 Condition CheckEitherSmi(Register first, 292 Condition CheckEitherSmi(Register first,
291 Register second, 293 Register second,
292 Register scratch = kScratchRegister); 294 Register scratch = kScratchRegister);
293 295
294 // Is the value the minimum smi value (since we are using 296 // Is the value the minimum smi value (since we are using
295 // two's complement numbers, negating the value is known to yield 297 // two's complement numbers, negating the value is known to yield
296 // a non-smi value). 298 // a non-smi value).
297 Condition CheckIsMinSmi(Register src); 299 Condition CheckIsMinSmi(Register src);
298 300
299 // Checks whether an 32-bit integer value is a valid for conversion 301 // Checks whether an 32-bit integer value is a valid for conversion
300 // to a smi. 302 // to a smi.
301 Condition CheckInteger32ValidSmiValue(Register src); 303 Condition CheckInteger32ValidSmiValue(Register src);
302 304
303 // Checks whether an 32-bit unsigned integer value is a valid for 305 // Checks whether an 32-bit unsigned integer value is a valid for
304 // conversion to a smi. 306 // conversion to a smi.
305 Condition CheckUInteger32ValidSmiValue(Register src); 307 Condition CheckUInteger32ValidSmiValue(Register src);
306 308
309 // Check whether src is a Smi, and set dst to zero if it is a smi,
310 // and to one if it isn't.
311 void CheckSmiToIndicator(Register dst, Register src);
312 void CheckSmiToIndicator(Register dst, const Operand& src);
313
307 // Test-and-jump functions. Typically combines a check function 314 // Test-and-jump functions. Typically combines a check function
308 // above with a conditional jump. 315 // above with a conditional jump.
309 316
310 // Jump if the value cannot be represented by a smi. 317 // Jump if the value cannot be represented by a smi.
311 template <typename LabelType> 318 template <typename LabelType>
312 void JumpIfNotValidSmiValue(Register src, LabelType* on_invalid); 319 void JumpIfNotValidSmiValue(Register src, LabelType* on_invalid);
313 320
314 // Jump if the unsigned integer value cannot be represented by a smi. 321 // Jump if the unsigned integer value cannot be represented by a smi.
315 template <typename LabelType> 322 template <typename LabelType>
316 void JumpIfUIntNotValidSmiValue(Register src, LabelType* on_invalid); 323 void JumpIfUIntNotValidSmiValue(Register src, LabelType* on_invalid);
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 void Move(const Operand& dst, Smi* source) { 538 void Move(const Operand& dst, Smi* source) {
532 Register constant = GetSmiConstant(source); 539 Register constant = GetSmiConstant(source);
533 movq(dst, constant); 540 movq(dst, constant);
534 } 541 }
535 542
536 void Push(Smi* smi); 543 void Push(Smi* smi);
537 void Test(const Operand& dst, Smi* source); 544 void Test(const Operand& dst, Smi* source);
538 545
539 // --------------------------------------------------------------------------- 546 // ---------------------------------------------------------------------------
540 // String macros. 547 // String macros.
548
549 // If object is a string, its map is loaded into object_map.
550 template <typename LabelType>
551 void JumpIfNotString(Register object,
552 Register object_map,
553 LabelType* not_string);
554
555
541 template <typename LabelType> 556 template <typename LabelType>
542 void JumpIfNotBothSequentialAsciiStrings(Register first_object, 557 void JumpIfNotBothSequentialAsciiStrings(Register first_object,
543 Register second_object, 558 Register second_object,
544 Register scratch1, 559 Register scratch1,
545 Register scratch2, 560 Register scratch2,
546 LabelType* on_not_both_flat_ascii); 561 LabelType* on_not_both_flat_ascii);
547 562
548 // Check whether the instance type represents a flat ascii string. Jump to the 563 // Check whether the instance type represents a flat ascii string. Jump to the
549 // label if not. If the instance type can be scratched specify same register 564 // label if not. If the instance type can be scratched specify same register
550 // for both instance type and scratch. 565 // for both instance type and scratch.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 602
588 // Control Flow 603 // Control Flow
589 void Jump(Address destination, RelocInfo::Mode rmode); 604 void Jump(Address destination, RelocInfo::Mode rmode);
590 void Jump(ExternalReference ext); 605 void Jump(ExternalReference ext);
591 void Jump(Handle<Code> code_object, RelocInfo::Mode rmode); 606 void Jump(Handle<Code> code_object, RelocInfo::Mode rmode);
592 607
593 void Call(Address destination, RelocInfo::Mode rmode); 608 void Call(Address destination, RelocInfo::Mode rmode);
594 void Call(ExternalReference ext); 609 void Call(ExternalReference ext);
595 void Call(Handle<Code> code_object, RelocInfo::Mode rmode); 610 void Call(Handle<Code> code_object, RelocInfo::Mode rmode);
596 611
612 // Emit call to the code we are currently generating.
613 void CallSelf() {
614 Handle<Code> self(reinterpret_cast<Code**>(CodeObject().location()));
615 Call(self, RelocInfo::CODE_TARGET);
616 }
617
618 // Non-x64 instructions.
619 // Push/pop all general purpose registers.
620 // Does not push rsp/rbp nor any of the assembler's special purpose registers
621 // (kScratchRegister, kSmiConstantRegister, kRootRegister).
622 void Pushad();
623 void Popad();
624 // Sets the stack as after performing Popad, without actually loading the
625 // registers.
626 void Dropad();
627
597 // Compare object type for heap object. 628 // Compare object type for heap object.
598 // Always use unsigned comparisons: above and below, not less and greater. 629 // Always use unsigned comparisons: above and below, not less and greater.
599 // Incoming register is heap_object and outgoing register is map. 630 // Incoming register is heap_object and outgoing register is map.
600 // They may be the same register, and may be kScratchRegister. 631 // They may be the same register, and may be kScratchRegister.
601 void CmpObjectType(Register heap_object, InstanceType type, Register map); 632 void CmpObjectType(Register heap_object, InstanceType type, Register map);
602 633
603 // Compare instance type for map. 634 // Compare instance type for map.
604 // Always use unsigned comparisons: above and below, not less and greater. 635 // Always use unsigned comparisons: above and below, not less and greater.
605 void CmpInstanceType(Register map, InstanceType type); 636 void CmpInstanceType(Register map, InstanceType type);
606 637
(...skipping 21 matching lines...) Expand all
628 659
629 // Abort execution if argument is not a number. Used in debug code. 660 // Abort execution if argument is not a number. Used in debug code.
630 void AbortIfNotNumber(Register object); 661 void AbortIfNotNumber(Register object);
631 662
632 // Abort execution if argument is a smi. Used in debug code. 663 // Abort execution if argument is a smi. Used in debug code.
633 void AbortIfSmi(Register object); 664 void AbortIfSmi(Register object);
634 665
635 // Abort execution if argument is not a smi. Used in debug code. 666 // Abort execution if argument is not a smi. Used in debug code.
636 void AbortIfNotSmi(Register object); 667 void AbortIfNotSmi(Register object);
637 668
669 // Abort execution if argument is a string. Used in debug code.
670 void AbortIfNotString(Register object);
671
638 // Abort execution if argument is not the root value with the given index. 672 // Abort execution if argument is not the root value with the given index.
639 void AbortIfNotRootValue(Register src, 673 void AbortIfNotRootValue(Register src,
640 Heap::RootListIndex root_value_index, 674 Heap::RootListIndex root_value_index,
641 const char* message); 675 const char* message);
642 676
643 // --------------------------------------------------------------------------- 677 // ---------------------------------------------------------------------------
644 // Exception handling 678 // Exception handling
645 679
646 // Push a new try handler and link into try handler chain. The return 680 // Push a new try handler and link into try handler chain. The return
647 // address must be pushed before calling this helper. 681 // address must be pushed before calling this helper.
648 void PushTryHandler(CodeLocation try_location, HandlerType type); 682 void PushTryHandler(CodeLocation try_location, HandlerType type);
649 683
650 // Unlink the stack handler on top of the stack from the try handler chain. 684 // Unlink the stack handler on top of the stack from the try handler chain.
651 void PopTryHandler(); 685 void PopTryHandler();
652 686
687 // Activate the top handler in the try hander chain and pass the
688 // thrown value.
689 void Throw(Register value);
690
691 // Propagate an uncatchable exception out of the current JS stack.
692 void ThrowUncatchable(UncatchableExceptionType type, Register value);
693
653 // --------------------------------------------------------------------------- 694 // ---------------------------------------------------------------------------
654 // Inline caching support 695 // Inline caching support
655 696
656 // Generate code for checking access rights - used for security checks 697 // Generate code for checking access rights - used for security checks
657 // on access to global objects across environments. The holder register 698 // on access to global objects across environments. The holder register
658 // is left untouched, but the scratch register and kScratchRegister, 699 // is left untouched, but the scratch register and kScratchRegister,
659 // which must be different, are clobbered. 700 // which must be different, are clobbered.
660 void CheckAccessGlobalProxy(Register holder_reg, 701 void CheckAccessGlobalProxy(Register holder_reg,
661 Register scratch, 702 Register scratch,
662 Label* miss); 703 Label* miss);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 // generate the code if necessary. Do not perform a GC but instead return 842 // generate the code if necessary. Do not perform a GC but instead return
802 // a retry after GC failure. 843 // a retry after GC failure.
803 MUST_USE_RESULT MaybeObject* TryTailCallStub(CodeStub* stub); 844 MUST_USE_RESULT MaybeObject* TryTailCallStub(CodeStub* stub);
804 845
805 // Return from a code stub after popping its arguments. 846 // Return from a code stub after popping its arguments.
806 void StubReturn(int argc); 847 void StubReturn(int argc);
807 848
808 // Call a runtime routine. 849 // Call a runtime routine.
809 void CallRuntime(Runtime::Function* f, int num_arguments); 850 void CallRuntime(Runtime::Function* f, int num_arguments);
810 851
852 // Call a runtime function and save the value of XMM registers.
853 void CallRuntimeSaveDoubles(Runtime::FunctionId id);
854
811 // Call a runtime function, returning the CodeStub object called. 855 // Call a runtime function, returning the CodeStub object called.
812 // Try to generate the stub code if necessary. Do not perform a GC 856 // Try to generate the stub code if necessary. Do not perform a GC
813 // but instead return a retry after GC failure. 857 // but instead return a retry after GC failure.
814 MUST_USE_RESULT MaybeObject* TryCallRuntime(Runtime::Function* f, 858 MUST_USE_RESULT MaybeObject* TryCallRuntime(Runtime::Function* f,
815 int num_arguments); 859 int num_arguments);
816 860
817 // Convenience function: Same as above, but takes the fid instead. 861 // Convenience function: Same as above, but takes the fid instead.
818 void CallRuntime(Runtime::FunctionId id, int num_arguments); 862 void CallRuntime(Runtime::FunctionId id, int num_arguments);
819 863
820 // Convenience function: Same as above, but takes the fid instead. 864 // Convenience function: Same as above, but takes the fid instead.
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 928
885 // Calculate the number of stack slots to reserve for arguments when calling a 929 // Calculate the number of stack slots to reserve for arguments when calling a
886 // C function. 930 // C function.
887 int ArgumentStackSlotsForCFunctionCall(int num_arguments); 931 int ArgumentStackSlotsForCFunctionCall(int num_arguments);
888 932
889 // --------------------------------------------------------------------------- 933 // ---------------------------------------------------------------------------
890 // Utilities 934 // Utilities
891 935
892 void Ret(); 936 void Ret();
893 937
938 // Return and drop arguments from stack, where the number of arguments
939 // may be bigger than 2^16 - 1. Requires a scratch register.
940 void Ret(int bytes_dropped, Register scratch);
941
894 Handle<Object> CodeObject() { return code_object_; } 942 Handle<Object> CodeObject() { return code_object_; }
895 943
896 944
897 // --------------------------------------------------------------------------- 945 // ---------------------------------------------------------------------------
898 // StatsCounter support 946 // StatsCounter support
899 947
900 void SetCounter(StatsCounter* counter, int value); 948 void SetCounter(StatsCounter* counter, int value);
901 void IncrementCounter(StatsCounter* counter, int value); 949 void IncrementCounter(StatsCounter* counter, int value);
902 void DecrementCounter(StatsCounter* counter, int value); 950 void DecrementCounter(StatsCounter* counter, int value);
903 951
(...skipping 16 matching lines...) Expand all
920 // Check that the stack is aligned. 968 // Check that the stack is aligned.
921 void CheckStackAlignment(); 969 void CheckStackAlignment();
922 970
923 // Verify restrictions about code generated in stubs. 971 // Verify restrictions about code generated in stubs.
924 void set_generating_stub(bool value) { generating_stub_ = value; } 972 void set_generating_stub(bool value) { generating_stub_ = value; }
925 bool generating_stub() { return generating_stub_; } 973 bool generating_stub() { return generating_stub_; }
926 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; } 974 void set_allow_stub_calls(bool value) { allow_stub_calls_ = value; }
927 bool allow_stub_calls() { return allow_stub_calls_; } 975 bool allow_stub_calls() { return allow_stub_calls_; }
928 976
929 private: 977 private:
978 // Order general registers are pushed by Pushad.
979 // rax, rcx, rdx, rbx, rsi, rdi, r8, r9, r11, r12, r14.
980 static int kSafepointPushRegisterIndices[Register::kNumRegisters];
981 static const int kNumSafepointSavedRegisters = 11;
982
930 bool generating_stub_; 983 bool generating_stub_;
931 bool allow_stub_calls_; 984 bool allow_stub_calls_;
932 985
933 // Returns a register holding the smi value. The register MUST NOT be 986 // Returns a register holding the smi value. The register MUST NOT be
934 // modified. It may be the "smi 1 constant" register. 987 // modified. It may be the "smi 1 constant" register.
935 Register GetSmiConstant(Smi* value); 988 Register GetSmiConstant(Smi* value);
936 989
937 // Moves the smi value to the destination register. 990 // Moves the smi value to the destination register.
938 void LoadSmiConstant(Register dst, Smi* value); 991 void LoadSmiConstant(Register dst, Smi* value);
939 992
(...skipping 10 matching lines...) Expand all
950 InvokeFlag flag); 1003 InvokeFlag flag);
951 1004
952 // Activation support. 1005 // Activation support.
953 void EnterFrame(StackFrame::Type type); 1006 void EnterFrame(StackFrame::Type type);
954 void LeaveFrame(StackFrame::Type type); 1007 void LeaveFrame(StackFrame::Type type);
955 1008
956 void EnterExitFramePrologue(bool save_rax); 1009 void EnterExitFramePrologue(bool save_rax);
957 1010
958 // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack 1011 // Allocates arg_stack_space * kPointerSize memory (not GCed) on the stack
959 // accessible via StackSpaceOperand. 1012 // accessible via StackSpaceOperand.
960 void EnterExitFrameEpilogue(int arg_stack_space); 1013 void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles);
961 1014
962 void LeaveExitFrameEpilogue(); 1015 void LeaveExitFrameEpilogue();
963 1016
964 // Allocation support helpers. 1017 // Allocation support helpers.
965 // Loads the top of new-space into the result register. 1018 // Loads the top of new-space into the result register.
966 // Otherwise the address of the new-space top is loaded into scratch (if 1019 // Otherwise the address of the new-space top is loaded into scratch (if
967 // scratch is valid), and the new-space top is loaded into result. 1020 // scratch is valid), and the new-space top is loaded into result.
968 void LoadAllocationTopHelper(Register result, 1021 void LoadAllocationTopHelper(Register result,
969 Register scratch, 1022 Register scratch,
970 AllocationFlags flags); 1023 AllocationFlags flags);
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 1486
1434 template <typename LabelType> 1487 template <typename LabelType>
1435 void MacroAssembler::SmiShiftLogicalRight(Register dst, 1488 void MacroAssembler::SmiShiftLogicalRight(Register dst,
1436 Register src1, 1489 Register src1,
1437 Register src2, 1490 Register src2,
1438 LabelType* on_not_smi_result) { 1491 LabelType* on_not_smi_result) {
1439 ASSERT(!dst.is(kScratchRegister)); 1492 ASSERT(!dst.is(kScratchRegister));
1440 ASSERT(!src1.is(kScratchRegister)); 1493 ASSERT(!src1.is(kScratchRegister));
1441 ASSERT(!src2.is(kScratchRegister)); 1494 ASSERT(!src2.is(kScratchRegister));
1442 ASSERT(!dst.is(rcx)); 1495 ASSERT(!dst.is(rcx));
1496 // dst and src1 can be the same, because the one case that bails out
1497 // is a shift by 0, which leaves dst, and therefore src1, unchanged.
1443 NearLabel result_ok; 1498 NearLabel result_ok;
1444 if (src1.is(rcx) || src2.is(rcx)) { 1499 if (src1.is(rcx) || src2.is(rcx)) {
1445 movq(kScratchRegister, rcx); 1500 movq(kScratchRegister, rcx);
1446 } 1501 }
1447 if (!dst.is(src1)) { 1502 if (!dst.is(src1)) {
1448 movq(dst, src1); 1503 movq(dst, src1);
1449 } 1504 }
1450 SmiToInteger32(rcx, src2); 1505 SmiToInteger32(rcx, src2);
1451 orl(rcx, Immediate(kSmiShift)); 1506 orl(rcx, Immediate(kSmiShift));
1452 shr_cl(dst); // Shift is rcx modulo 0x1f + 32. 1507 shr_cl(dst); // Shift is rcx modulo 0x1f + 32.
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1567 template <typename LabelType> 1622 template <typename LabelType>
1568 void MacroAssembler::JumpUnlessBothNonNegativeSmi(Register src1, 1623 void MacroAssembler::JumpUnlessBothNonNegativeSmi(Register src1,
1569 Register src2, 1624 Register src2,
1570 LabelType* on_not_both_smi) { 1625 LabelType* on_not_both_smi) {
1571 Condition both_smi = CheckBothNonNegativeSmi(src1, src2); 1626 Condition both_smi = CheckBothNonNegativeSmi(src1, src2);
1572 j(NegateCondition(both_smi), on_not_both_smi); 1627 j(NegateCondition(both_smi), on_not_both_smi);
1573 } 1628 }
1574 1629
1575 1630
1576 template <typename LabelType> 1631 template <typename LabelType>
1632 void MacroAssembler::JumpIfNotString(Register object,
1633 Register object_map,
1634 LabelType* not_string) {
1635 Condition is_smi = CheckSmi(object);
1636 j(is_smi, not_string);
1637 CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map);
1638 j(above_equal, not_string);
1639 }
1640
1641
1642 template <typename LabelType>
1577 void MacroAssembler::JumpIfNotBothSequentialAsciiStrings(Register first_object, 1643 void MacroAssembler::JumpIfNotBothSequentialAsciiStrings(Register first_object,
1578 Register second_object, 1644 Register second_object,
1579 Register scratch1, 1645 Register scratch1,
1580 Register scratch2, 1646 Register scratch2,
1581 LabelType* on_fail) { 1647 LabelType* on_fail) {
1582 // Check that both objects are not smis. 1648 // Check that both objects are not smis.
1583 Condition either_smi = CheckEitherSmi(first_object, second_object); 1649 Condition either_smi = CheckEitherSmi(first_object, second_object);
1584 j(either_smi, on_fail); 1650 j(either_smi, on_fail);
1585 1651
1586 // Load instance type for both strings. 1652 // Load instance type for both strings.
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1750 Jump(adaptor, RelocInfo::CODE_TARGET); 1816 Jump(adaptor, RelocInfo::CODE_TARGET);
1751 } 1817 }
1752 bind(&invoke); 1818 bind(&invoke);
1753 } 1819 }
1754 } 1820 }
1755 1821
1756 1822
1757 } } // namespace v8::internal 1823 } } // namespace v8::internal
1758 1824
1759 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_ 1825 #endif // V8_X64_MACRO_ASSEMBLER_X64_H_
OLDNEW
« no previous file with comments | « src/x64/lithium-x64.cc ('k') | src/x64/macro-assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698