Revision f230a1cf deps/v8/src/x64/macro-assembler-x64.h
deps/v8/src/x64/macro-assembler-x64.h | ||
---|---|---|
282 | 282 |
void DebugBreak(); |
283 | 283 |
#endif |
284 | 284 |
|
285 |
// Generates function and stub prologue code. |
|
286 |
void Prologue(PrologueFrameMode frame_mode); |
|
287 |
|
|
285 | 288 |
// Enter specific kind of exit frame; either in normal or |
286 | 289 |
// debug mode. Expects the number of arguments in register rax and |
287 | 290 |
// sets up the number of arguments in register rdi and the pointer |
... | ... | |
302 | 305 |
|
303 | 306 |
// Leave the current exit frame. Expects/provides the return value in |
304 | 307 |
// register rax (untouched). |
305 |
void LeaveApiExitFrame(); |
|
308 |
void LeaveApiExitFrame(bool restore_context);
|
|
306 | 309 |
|
307 | 310 |
// Push and pop the registers that can hold pointers. |
308 | 311 |
void PushSafepointRegisters() { Pushad(); } |
... | ... | |
532 | 535 |
// Smis represent a subset of integers. The subset is always equivalent to |
533 | 536 |
// a two's complement interpretation of a fixed number of bits. |
534 | 537 |
|
535 |
// Optimistically adds an integer constant to a supposed smi. |
|
536 |
// If the src is not a smi, or the result is not a smi, jump to |
|
537 |
// the label. |
|
538 |
void SmiTryAddConstant(Register dst, |
|
539 |
Register src, |
|
540 |
Smi* constant, |
|
541 |
Label* on_not_smi_result, |
|
542 |
Label::Distance near_jump = Label::kFar); |
|
543 |
|
|
544 | 538 |
// Add an integer constant to a tagged smi, giving a tagged smi as result. |
545 | 539 |
// No overflow testing on the result is done. |
546 | 540 |
void SmiAddConstant(Register dst, Register src, Smi* constant); |
... | ... | |
578 | 572 |
Label::Distance near_jump = Label::kFar); |
579 | 573 |
|
580 | 574 |
// Adds smi values and return the result as a smi. |
581 |
// If dst is src1, then src1 will be destroyed, even if
|
|
582 |
// the operation is unsuccessful.
|
|
575 |
// If dst is src1, then src1 will be destroyed if the operation is
|
|
576 |
// successful, otherwise kept intact.
|
|
583 | 577 |
void SmiAdd(Register dst, |
584 | 578 |
Register src1, |
585 | 579 |
Register src2, |
... | ... | |
596 | 590 |
Register src2); |
597 | 591 |
|
598 | 592 |
// Subtracts smi values and return the result as a smi. |
599 |
// If dst is src1, then src1 will be destroyed, even if
|
|
600 |
// the operation is unsuccessful.
|
|
593 |
// If dst is src1, then src1 will be destroyed if the operation is
|
|
594 |
// successful, otherwise kept intact.
|
|
601 | 595 |
void SmiSub(Register dst, |
602 | 596 |
Register src1, |
603 | 597 |
Register src2, |
604 | 598 |
Label* on_not_smi_result, |
605 | 599 |
Label::Distance near_jump = Label::kFar); |
606 |
|
|
607 |
void SmiSub(Register dst, |
|
608 |
Register src1, |
|
609 |
Register src2); |
|
610 |
|
|
611 | 600 |
void SmiSub(Register dst, |
612 | 601 |
Register src1, |
613 | 602 |
const Operand& src2, |
... | ... | |
616 | 605 |
|
617 | 606 |
void SmiSub(Register dst, |
618 | 607 |
Register src1, |
608 |
Register src2); |
|
609 |
|
|
610 |
void SmiSub(Register dst, |
|
611 |
Register src1, |
|
619 | 612 |
const Operand& src2); |
620 | 613 |
|
621 | 614 |
// Multiplies smi values and return the result as a smi, |
... | ... | |
739 | 732 |
// --------------------------------------------------------------------------- |
740 | 733 |
// String macros. |
741 | 734 |
|
735 |
// Generate code to do a lookup in the number string cache. If the number in |
|
736 |
// the register object is found in the cache the generated code falls through |
|
737 |
// with the result in the result register. The object and the result register |
|
738 |
// can be the same. If the number is not found in the cache the code jumps to |
|
739 |
// the label not_found with only the content of register object unchanged. |
|
740 |
void LookupNumberStringCache(Register object, |
|
741 |
Register result, |
|
742 |
Register scratch1, |
|
743 |
Register scratch2, |
|
744 |
Label* not_found); |
|
745 |
|
|
742 | 746 |
// If object is a string, its map is loaded into object_map. |
743 | 747 |
void JumpIfNotString(Register object, |
744 | 748 |
Register object_map, |
... | ... | |
780 | 784 |
// --------------------------------------------------------------------------- |
781 | 785 |
// Macro instructions. |
782 | 786 |
|
787 |
// Load/store with specific representation. |
|
788 |
void Load(Register dst, const Operand& src, Representation r); |
|
789 |
void Store(const Operand& dst, Register src, Representation r); |
|
790 |
|
|
783 | 791 |
// Load a register with a long value as efficiently as possible. |
784 | 792 |
void Set(Register dst, int64_t x); |
785 | 793 |
void Set(const Operand& dst, int64_t x); |
786 | 794 |
|
795 |
// cvtsi2sd instruction only writes to the low 64-bit of dst register, which |
|
796 |
// hinders register renaming and makes dependence chains longer. So we use |
|
797 |
// xorps to clear the dst register before cvtsi2sd to solve this issue. |
|
798 |
void Cvtlsi2sd(XMMRegister dst, Register src); |
|
799 |
void Cvtlsi2sd(XMMRegister dst, const Operand& src); |
|
800 |
|
|
787 | 801 |
// Move if the registers are not identical. |
788 | 802 |
void Move(Register target, Register source); |
789 | 803 |
|
... | ... | |
801 | 815 |
|
802 | 816 |
// Load a heap object and handle the case of new-space objects by |
803 | 817 |
// indirecting via a global cell. |
804 |
void LoadHeapObject(Register result, Handle<HeapObject> object); |
|
805 |
void CmpHeapObject(Register reg, Handle<HeapObject> object); |
|
806 |
void PushHeapObject(Handle<HeapObject> object); |
|
807 |
|
|
808 |
void LoadObject(Register result, Handle<Object> object) { |
|
809 |
AllowDeferredHandleDereference heap_object_check; |
|
810 |
if (object->IsHeapObject()) { |
|
811 |
LoadHeapObject(result, Handle<HeapObject>::cast(object)); |
|
812 |
} else { |
|
813 |
Move(result, object); |
|
814 |
} |
|
815 |
} |
|
816 |
|
|
817 |
void CmpObject(Register reg, Handle<Object> object) { |
|
818 |
AllowDeferredHandleDereference heap_object_check; |
|
819 |
if (object->IsHeapObject()) { |
|
820 |
CmpHeapObject(reg, Handle<HeapObject>::cast(object)); |
|
821 |
} else { |
|
822 |
Cmp(reg, object); |
|
823 |
} |
|
824 |
} |
|
818 |
void MoveHeapObject(Register result, Handle<Object> object); |
|
825 | 819 |
|
826 | 820 |
// Load a global cell into a register. |
827 | 821 |
void LoadGlobalCell(Register dst, Handle<Cell> cell); |
... | ... | |
835 | 829 |
void Pop(Register dst) { pop(dst); } |
836 | 830 |
void PushReturnAddressFrom(Register src) { push(src); } |
837 | 831 |
void PopReturnAddressTo(Register dst) { pop(dst); } |
832 |
void MoveDouble(Register dst, const Operand& src) { movq(dst, src); } |
|
833 |
void MoveDouble(const Operand& dst, Register src) { movq(dst, src); } |
|
838 | 834 |
|
839 | 835 |
// Control Flow |
840 | 836 |
void Jump(Address destination, RelocInfo::Mode rmode); |
... | ... | |
1104 | 1100 |
Label* gc_required, |
1105 | 1101 |
AllocationFlags flags); |
1106 | 1102 |
|
1103 |
// Record a JS object allocation if allocations tracking mode is on. |
|
1104 |
void RecordObjectAllocation(Isolate* isolate, |
|
1105 |
Register object, |
|
1106 |
Register object_size); |
|
1107 |
|
|
1108 |
void RecordObjectAllocation(Isolate* isolate, |
|
1109 |
Register object, |
|
1110 |
int object_size); |
|
1111 |
|
|
1107 | 1112 |
// Undo allocation in new space. The object passed and objects allocated after |
1108 | 1113 |
// it will no longer be allocated. Make sure that no pointers are left to the |
1109 | 1114 |
// object(s) no longer allocated as they would be invalid when allocation is |
... | ... | |
1232 | 1237 |
void StubReturn(int argc); |
1233 | 1238 |
|
1234 | 1239 |
// Call a runtime routine. |
1235 |
void CallRuntime(const Runtime::Function* f, int num_arguments); |
|
1240 |
void CallRuntime(const Runtime::Function* f, |
|
1241 |
int num_arguments, |
|
1242 |
SaveFPRegsMode save_doubles = kDontSaveFPRegs); |
|
1236 | 1243 |
|
1237 | 1244 |
// Call a runtime function and save the value of XMM registers. |
1238 |
void CallRuntimeSaveDoubles(Runtime::FunctionId id); |
|
1245 |
void CallRuntimeSaveDoubles(Runtime::FunctionId id) { |
|
1246 |
const Runtime::Function* function = Runtime::FunctionForId(id); |
|
1247 |
CallRuntime(function, function->nargs, kSaveFPRegs); |
|
1248 |
} |
|
1239 | 1249 |
|
1240 | 1250 |
// Convenience function: Same as above, but takes the fid instead. |
1241 |
void CallRuntime(Runtime::FunctionId id, int num_arguments); |
|
1251 |
void CallRuntime(Runtime::FunctionId id, int num_arguments) { |
|
1252 |
CallRuntime(Runtime::FunctionForId(id), num_arguments); |
|
1253 |
} |
|
1242 | 1254 |
|
1243 | 1255 |
// Convenience function: call an external reference. |
1244 | 1256 |
void CallExternalReference(const ExternalReference& ext, |
... | ... | |
1274 | 1286 |
Address thunk_address, |
1275 | 1287 |
Register thunk_last_arg, |
1276 | 1288 |
int stack_space, |
1277 |
int return_value_offset_from_rbp); |
|
1289 |
Operand return_value_operand, |
|
1290 |
Operand* context_restore_operand); |
|
1278 | 1291 |
|
1279 | 1292 |
// Before calling a C-function from generated code, align arguments on stack. |
1280 | 1293 |
// After aligning the frame, arguments must be stored in rsp[0], rsp[8], |
... | ... | |
1384 | 1397 |
// to another type. |
1385 | 1398 |
// On entry, receiver_reg should point to the array object. |
1386 | 1399 |
// scratch_reg gets clobbered. |
1387 |
// If allocation info is present, condition flags are set to equal |
|
1400 |
// If allocation info is present, condition flags are set to equal.
|
|
1388 | 1401 |
void TestJSArrayForAllocationMemento(Register receiver_reg, |
1389 |
Register scratch_reg); |
|
1402 |
Register scratch_reg, |
|
1403 |
Label* no_memento_found); |
|
1404 |
|
|
1405 |
void JumpIfJSArrayHasAllocationMemento(Register receiver_reg, |
|
1406 |
Register scratch_reg, |
|
1407 |
Label* memento_found) { |
|
1408 |
Label no_memento_found; |
|
1409 |
TestJSArrayForAllocationMemento(receiver_reg, scratch_reg, |
|
1410 |
&no_memento_found); |
|
1411 |
j(equal, memento_found); |
|
1412 |
bind(&no_memento_found); |
|
1413 |
} |
|
1390 | 1414 |
|
1391 | 1415 |
private: |
1392 | 1416 |
// Order general registers are pushed by Pushad. |
... | ... | |
1430 | 1454 |
// accessible via StackSpaceOperand. |
1431 | 1455 |
void EnterExitFrameEpilogue(int arg_stack_space, bool save_doubles); |
1432 | 1456 |
|
1433 |
void LeaveExitFrameEpilogue(); |
|
1457 |
void LeaveExitFrameEpilogue(bool restore_context);
|
|
1434 | 1458 |
|
1435 | 1459 |
// Allocation support helpers. |
1436 | 1460 |
// Loads the top of new-space into the result register. |
Also available in: Unified diff