XVimProject / XVim2

Vim key-bindings for Xcode 9
MIT License
2.31k stars 181 forks source link

Refactor assembly code #352

Closed r-plus closed 3 years ago

r-plus commented 3 years ago

While researching assembly code porting to arm64, I found rbx, r12-r15 and xmm0-7 register is not used around invoking swift method. Additionally, rest of using registers rsi, rdi, rdx, rcx, r8 and r9 are not callee-save registers.

This PR remove operations using that registers and refactoring before support arm.

r-plus commented 3 years ago

~Ah, I’m wrong. rsi and rdi are non volatile register, should restore before return.~

r-plus commented 3 years ago

uum, rsi and rdi registers as volatile only in Windows. We are not necessary save/restore its registers on mac. callee-save registers are rbx, rbp, r12-r15 for mac.

https://www.agner.org/optimize/calling_conventions.pdf 6 Register usage

JugglerShu commented 3 years ago

I haven't read the code around this assembly yet but one question I have is why we don't need to save registers on a which which we previously did?

r-plus commented 3 years ago

@JugglerShu thanks for your response. Save and restore registers operation is only necessary for non-volatile registers that often called as callee-save register. In the x64 macOS, rbx, rbp, r12-r15 registers are non-volatile.

SourceEditorViewWrapper.s implemented function is not use that registers. This is reason why I removed save and restore but not using non-volatile registers operation and for volatile registers.

Scratch registers are registers that can be used for temporary storage without restrictions (also called caller-save or volatile registers). Callee-save registers are registers that you have to save before using them and restore after using them (also called non-volatile registers). You can rely on these registers having the same value after a call as before the call.

from page.11 https://www.agner.org/optimize/calling_conventions.pdf

スクリーンショット 2021-01-14 11 29 32
JugglerShu commented 3 years ago

Let me explain my thoughts (sorry I should take time to investigate more but writing this before that.) So these registers must not changed between before/after function call. What I'm worrying is if any method called via this assembly (at callq *(%rsp)) changes these registers they may be different. What I'm not sure yet is if these method saves these registers internally. If they do we don't need to save these registers as your code. Do you mean that any method called via callq *(%rsp) never changes these registers?

r-plus commented 3 years ago

Yes, called swift method is callee, and our assembly function is caller in that case. callee must restore the non-volatile registers before return, so caller can expect non-volatile registers value will not change after calling function by callq *(%rsp)

You can rely on these registers having the same value after a call as before the call.

again quote about it.

JugglerShu commented 3 years ago

So do you want to merge this first? or do you want to close this and merge this change as part of Arm support?

r-plus commented 3 years ago

I want to merge this PR first. I believe reachability to this conversation from commit/blame is maybe helpful for the future...

r-plus commented 3 years ago

thanks for your response. This changes are stable in my full day job use case on intel mac. I'll merge this, let me know if you have any issue.