Messages in this thread | | | Date | Wed, 30 Aug 2023 22:09:51 +0700 | From | Ammar Faizi <> | Subject | Re: [RFC PATCH v1 2/5] tools/nolibc: x86-64: Use `rep stosb` for `memset()` |
| |
On Wed, Aug 30, 2023 at 09:24:45PM +0700, Alviro Iskandar Setiawan wrote: > Just a small idea to shrink this more, "mov %rdi, %rdx" and "mov %rdx, > %rax" can be replaced with "push %rdi" and "pop %rax" (they are just a > byte). So we can save 4 bytes more. > > 0000000000001500 <memset>: > 1500: 48 89 f0 mov %rsi,%rax > 1503: 48 89 d1 mov %rdx,%rcx > 1506: 57 push %rdi > 1507: f3 aa rep stos %al,%es:(%rdi) > 1509: 58 pop %rax > 150a: c3 ret > > But I know you don't like it because it costs extra memory access.
Yes, that's an extra memory access. But I believe it doesn't hurt someone targetting -Os. In many cases, the compilers use push/pop to align the stack before a 'call' instruction. If they want to avoid extra memory access, they could have used "subq $8, %rsp" and "addq $8, %rsp".
For example: https://godbolt.org/z/Tzc1xWGEn
C code: ``` int fx(int b); int fy(int a) { return 1 + fx(a); } ```
Targetting -Os, both clang and gcc compile it to: ``` fy: pushq %rax call fx popq %rdx incl %eax ret ```
Targetting -O2: ``` fy: subq $8, %rsp call fx addq $8, %rsp addl $1, %eax ret ```
That pushq/popq pair doesn't actually preserve anything; it's just to align the %rsp at 16 bytes on 'call'. IOW, sometimes having extra memory access to get a smaller code size is acceptable.
-- Ammar Faizi
| |