about summary refs log tree commit diff stats
path: root/302stack_allocate.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-07-05 12:13:28 -0700
committerKartik Agaram <vc@akkartik.com>2020-07-05 12:13:28 -0700
commitc09c91e185aad8e01b570c2569e13c1e429d2f99 (patch)
tree52a5ae1494ad5b7b2319411815dc45510e761c24 /302stack_allocate.subx
parentf2c5b05374186f9422cfdaf1ada096e39ac91a8b (diff)
downloadmu-c09c91e185aad8e01b570c2569e13c1e429d2f99.tar.gz
6612 - reorganize layers
Diffstat (limited to '302stack_allocate.subx')
-rw-r--r--302stack_allocate.subx62
1 files changed, 62 insertions, 0 deletions
diff --git a/302stack_allocate.subx b/302stack_allocate.subx
new file mode 100644
index 00000000..02ad84f2
--- /dev/null
+++ b/302stack_allocate.subx
@@ -0,0 +1,62 @@
+# A function which pushes n zeros on the stack.
+# Not really useful to call manually.
+# The Mu compiler uses it when defining arrays on the stack.
+
+== code
+
+#? Entry:
+#?     # . prologue
+#?     89/<- %ebp 4/r32/esp
+#?     #
+#?     68/push 0xfcfdfeff/imm32
+#?     b8/copy-to-eax 0x34353637/imm32
+#? $dump-stack0:
+#?     (push-n-zero-bytes 4)
+#?     68/push 0x20/imm32
+#? $dump-stack9:
+#?     b8/copy-to-eax 1/imm32/exit
+#?     cd/syscall 0x80/imm8
+
+# This is not a regular function, so it won't be idiomatic.
+# Registers must be properly restored.
+# Registers can be spilled, but that modifies the stack and needs to be
+# cleaned up.
+
+# Overhead:
+#   62 + n*6 instructions to push n bytes.
+# If we just emitted code to push n zeroes, it would be:
+#   5 bytes for 4 zero bytes, so 1.25 bytes per zero. And that's not even
+#   instructions.
+# But on the other hand it would destroy the instruction cache, where this
+# approach requires 15 instructions, fixed.
+
+# n must be positive
+push-n-zero-bytes:  # n: int
+$push-n-zero-bytes:prologue:
+    89/<- *Push-n-zero-bytes-ebp 5/r32/ebp  # spill ebp without affecting stack
+    89/<- %ebp 4/r32/esp
+$push-n-zero-bytes:copy-ra:
+    # -- esp = ebp
+    50/push-eax
+    # -- esp+8 = ebp+4
+    # -- esp+4 = ebp
+    8b/-> *(esp+4) 0/r32/eax
+    2b/subtract *(ebp+4) 4/r32/esp
+    # -- esp+4+n = ebp
+    89/<- *(esp+4) 0/r32/eax
+    58/pop-to-eax
+    # -- esp+n = ebp
+$push-n-zero-bytes:bulk-cleaning:
+    89/<- *Push-n-zero-bytes-esp 4/r32/esp
+    81 0/subop/add *Push-n-zero-bytes-esp 4/imm32
+    81 0/subop/add *(ebp+4) 4/imm32
+    (zero-out *Push-n-zero-bytes-esp *(ebp+4))  # n+4
+$push-n-zero-bytes:epilogue:
+    8b/-> *Push-n-zero-bytes-ebp 5/r32/ebp  # restore spill
+    c3/return
+
+== data
+Push-n-zero-bytes-ebp:  # (addr int)
+  0/imm32
+Push-n-zero-bytes-esp:  # (addr int)
+  0/imm32