about summary refs log tree commit diff stats
path: root/subx/074print-int-decimal.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-05-04 14:39:45 -0700
committerKartik Agaram <vc@akkartik.com>2019-05-04 14:55:44 -0700
commit37aa2bf3e8c3b22c6b87925148cf938d1c1cc185 (patch)
treeb295b9bece049031c082a1fd1c46003c1dc8c41b /subx/074print-int-decimal.subx
parent85a3e39cd5b4d11bc38d2fc400015770e1994774 (diff)
downloadmu-37aa2bf3e8c3b22c6b87925148cf938d1c1cc185.tar.gz
5142
Hoist address computation out of the loop.

I'm giving in to the temptation to optimize here, and violating my own
rule of minimizing local variables by introducing 'curr'. My fig leaf is
that the number of instructions inside the loop goes down, and duplicating
inside the loop may be distracting to readers.
Diffstat (limited to 'subx/074print-int-decimal.subx')
-rw-r--r--subx/074print-int-decimal.subx32
1 files changed, 20 insertions, 12 deletions
diff --git a/subx/074print-int-decimal.subx b/subx/074print-int-decimal.subx
index a3f9bf9e..7f9dadc5 100644
--- a/subx/074print-int-decimal.subx
+++ b/subx/074print-int-decimal.subx
@@ -25,11 +25,15 @@ print-int32-decimal:  # out : (address stream), n : int32
     #     if (EAX == 0) break
     #   if n < 0
     #     push '-'
+    #   w = out->write
+    #   curr = &out->data[out->write]
     #   while true
     #     pop into EAX
     #     if (EAX == sentinel) break
-    #     out->data[out->write] = AL
-    #     ++out->write
+    #     *curr = AL
+    #     ++curr
+    #     ++w
+    #   out->write = w
     # (based on K&R itoa: https://en.wikibooks.org/wiki/C_Programming/stdlib.h/itoa)
     # (this pseudocode contains registers because operations like division
     # require specific registers in x86)
@@ -47,7 +51,7 @@ print-int32-decimal:  # out : (address stream), n : int32
     # push sentinel
     68/push  0/imm32/sentinel
     # EAX = abs(n)
-    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           0/r32/EAX   0xc/disp8       .                 # EAX = *(EBP+12)
+    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           0/r32/EAX   0xc/disp8       .                 # copy *(EBP+12) to EAX
     3d/compare-EAX-with  0/imm32
     7d/jump-if-greater-or-equal  $print-int32-decimal:read-loop/disp8
     f7  3/subop/negate              3/mod/direct    0/rm32/EAX    .           .             .           .           .               .                 # negate EAX
@@ -70,22 +74,26 @@ $print-int32-decimal:read-break:
 $print-int32-decimal:write:
     # EDI = out
     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           7/r32/EDI   8/disp8         .                 # copy *(EBP+8) to EDI
+    # w/EDX = out->write
+    8b/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           2/r32/EDX   .               .                 # copy *EDI to EDX
+    # curr/ECX = &out->data[out->write]
+    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    7/base/EDI  2/index/EDX   .           1/r32/ECX   0xc/disp8       .                 # copy EBX+EDX+12 to ECX
 $print-int32-decimal:write-loop:
     # pop into EAX
     58/pop-to-EAX
     # if (EAX == sentinel) break
     3d/compare-EAX-and  0/imm32/sentinel
-    74/jump-if-equal  $print-int32-decimal:end/disp8
-    # out->data[out->write] = AL
-    # . ECX = out->write
-    8b/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           1/r32/ECX   .               .                 # copy *EDI to ECX
-    # . ECX = &out->data[out->write]
-    8d/copy-address                 1/mod/*+disp8   4/rm32/sib    7/base/EDI  1/index/ECX   .           1/r32/ECX   0xc/disp8       .                 # copy EBX+ECX+12 to ECX
-    # . out->data[out->write] = AL
+    74/jump-if-equal  $print-int32-decimal:write-break/disp8
+    # *curr = AL
     88/copy-byte                    0/mod/indirect  1/rm32/ECX    .           .             .           0/r32/AL    .               .                 # copy AL to byte at *ECX
-    # out->write++
-    ff          0/subop/increment   0/mod/indirect  7/rm32/EDI    .           .             .           .           .               .                 # increment *EDI
+    # ++curr
+    41/increment-ECX
+    # ++w
+    42/increment-EDX
     eb/jump  $print-int32-decimal:write-loop/disp8
+$print-int32-decimal:write-break:
+    # out->write = w
+    89/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           2/r32/EDX   .               .                 # copy EDX to *EDI
 $print-int32-decimal:end:
     # . restore registers
     5f/pop-to-EDI