about summary refs log tree commit diff stats
path: root/Readme.md
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2014-11-26 08:48:06 -0800
committerKartik K. Agaram <vc@akkartik.com>2014-11-26 08:48:06 -0800
commit711dd36f9eb81fcd51a5fd891b7dae7e7aa53de4 (patch)
tree12874de03c974e2a5a2ef00a2266d96aed7be9f4 /Readme.md
parent797a46d51c80554d05edb3f64211066b0c940972 (diff)
downloadmu-711dd36f9eb81fcd51a5fd891b7dae7e7aa53de4.tar.gz
331
Diffstat (limited to 'Readme.md')
-rw-r--r--Readme.md4
1 files changed, 1 insertions, 3 deletions
diff --git a/Readme.md b/Readme.md
index ab36e9ed..cf7388cd 100644
--- a/Readme.md
+++ b/Readme.md
@@ -163,9 +163,7 @@ Another example, this time with concurrency.
 Notice that it repeatedly prints either '34' or '35' at random. Hit ctrl-c to
 stop.
 
----
-
-Another example forks two 'routines' that communicate over a channel:
+Yet another example forks two 'routines' that communicate over a channel:
 
 ```shell
   $ ./anarki/arc mu.arc channel.mu
36699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
# 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