diff options
Diffstat (limited to 'zap/source/amd64/mem/foreach.S')
-rw-r--r-- | zap/source/amd64/mem/foreach.S | 54 |
1 files changed, 29 insertions, 25 deletions
diff --git a/zap/source/amd64/mem/foreach.S b/zap/source/amd64/mem/foreach.S index f19bcfa..6766933 100644 --- a/zap/source/amd64/mem/foreach.S +++ b/zap/source/amd64/mem/foreach.S @@ -5,51 +5,55 @@ .globl zap_foreach zap_foreach: - # rbx: Address of the current element. - # r12: Address of the element after the last input element. - # r13: Size of each input element. - # r14: Address of the function. +# Address of the current element: +#define addr %rbx +# Address of the element after the last input element: +#define afterbuf %r12 +# Size of each input element: +#define sz %r13 +# Address of the function: +#define fn %r14 # We're gonna use callee-saved registers for storing values so they don't get overwritten with each function call. # Push the callee-saved registers: - pushq %rbx - pushq %r12 - pushq %r13 - pushq %r14 + pushq addr + pushq afterbuf + pushq sz + pushq fn # Move registers into place: - movq %rdi,%rbx - movq %rsi,%r13 - movq %rcx,%r14 + movq %rdi,addr + movq %rsi,sz + movq %rcx,fn # Get the one-past-the-end address: - movq %rdx,%r12 - imulq %r13,%r12 # Calculate the array size in bytes (sz * num). We're using signed multiply because the equivalent using the unsigned instruction would use more instructions. - addq %rbx,%r12 + movq %rdx,afterbuf + imulq sz,afterbuf # afterbuf *= sz // Calculate the array size in bytes (sz * num). We're using signed multiply because the equivalent using the unsigned instruction would use more instructions. + addq addr,afterbuf # afterbuf += addr # Iterate through the array: .loop: # Check if we have reached the one-past-the-end address: - cmpq %rbx,%r12 - je .done + cmpq addr,afterbuf # if (addr == afterbuf) + je .done # goto done # Call the provided function: - movq %rbx,%rdi # Provide the current address to the function. - call *%r14 # We don't need to save any registers for this as we only use callee-saved registers. + movq addr,%rdi # // Provide the current address to the function. + call *fn # fn(addr) // We don't need to save any registers for this as we only use callee-saved registers. # Continue to the next element: - addq %r13,%rbx - jmp .loop + addq sz,addr # addr += sz + jmp .loop # goto loop # Finish: .done: # Restore the callee-saved registers: - popq %r14 - popq %r13 - popq %r12 - popq %rbx + popq fn + popq sz + popq afterbuf + popq addr - ret + ret # return |