summaryrefslogtreecommitdiff
path: root/zap/source/amd64/mem/foreach.S
diff options
context:
space:
mode:
Diffstat (limited to 'zap/source/amd64/mem/foreach.S')
-rw-r--r--zap/source/amd64/mem/foreach.S54
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