* Get all callee-save registers. */
| 706 | * Get all callee-save registers. |
| 707 | */ |
| 708 | const int *getCallerSaveRegs(bool sysv, bool clean, bool state, |
| 709 | bool conditional, size_t num_args) |
| 710 | { |
| 711 | // If "state", then we must save the entire register state: |
| 712 | static const int state_save[] = |
| 713 | { |
| 714 | RAX_IDX, RCX_IDX, RDX_IDX, RBX_IDX, RBP_IDX, RSI_IDX, RDI_IDX, R8_IDX, |
| 715 | R9_IDX, R10_IDX, R11_IDX, R12_IDX, R13_IDX, R14_IDX, R15_IDX, |
| 716 | FLAGS_IDX, RSP_IDX, RIP_IDX, -1 |
| 717 | }; |
| 718 | if (state) |
| 719 | return state_save; |
| 720 | |
| 721 | // For clean calls, we must save all caller save registers according |
| 722 | // to the corresponding ABI. Notes: |
| 723 | // - To support `conditional', %rcx must be saved first. |
| 724 | // - %rax must be saved before %rflags. |
| 725 | static const int clean_sysv_save[] = |
| 726 | { |
| 727 | RCX_IDX, RAX_IDX, FLAGS_IDX, R11_IDX, R10_IDX, R9_IDX, R8_IDX, |
| 728 | RDX_IDX, RSI_IDX, RDI_IDX, -1 |
| 729 | }; |
| 730 | static const int clean_win64_save[] = |
| 731 | { |
| 732 | RCX_IDX, RAX_IDX, FLAGS_IDX, R11_IDX, R10_IDX, R9_IDX, R8_IDX, |
| 733 | RDX_IDX, -1 |
| 734 | }; |
| 735 | const int *clean_save = (sysv? clean_sysv_save: clean_win64_save); |
| 736 | if (clean) |
| 737 | return clean_save; |
| 738 | |
| 739 | // For `naked' calls, we only save the number of registers actually used |
| 740 | // by args. |
| 741 | static const int naked_sysv_save[] = |
| 742 | { |
| 743 | R11_IDX, R10_IDX, R9_IDX, R8_IDX, RCX_IDX, RDX_IDX, RSI_IDX, RDI_IDX, |
| 744 | -1 |
| 745 | }; |
| 746 | static const int naked_win64_save[] = |
| 747 | { |
| 748 | R11_IDX, R10_IDX, R9_IDX, R8_IDX, RDX_IDX, RCX_IDX, -1 |
| 749 | }; |
| 750 | const int *naked_save = (sysv? naked_sysv_save: naked_win64_save); |
| 751 | unsigned naked_len = (sysv? 8: 6); |
| 752 | if (!conditional) |
| 753 | return naked_save + (naked_len - num_args); |
| 754 | |
| 755 | // For `conditional+naked' calls. %rax must be saved first: |
| 756 | if (sysv) |
| 757 | { |
| 758 | static const int conditional_save[][10] = |
| 759 | { |
| 760 | {RAX_IDX, -1}, |
| 761 | {RAX_IDX, RDI_IDX, -1}, |
| 762 | {RAX_IDX, RSI_IDX, RDI_IDX, -1}, |
| 763 | {RAX_IDX, RDX_IDX, RSI_IDX, RDI_IDX, -1}, |
| 764 | {RAX_IDX, RCX_IDX, RDX_IDX, RSI_IDX, RDI_IDX, -1}, |
| 765 | {RAX_IDX, R8_IDX, RCX_IDX, RDX_IDX, RSI_IDX, RDI_IDX, -1}, |
no outgoing calls
no test coverage detected