about summary refs log tree commit diff stats
path: root/054string-equal.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-01-29 17:34:07 -0800
committerKartik Agaram <vc@akkartik.com>2020-01-29 17:34:07 -0800
commitd20fbf71c379b6f51a3edd57cc4a1d2ad37ed8e0 (patch)
treeb6d0467a7facdda256e9acb25442be8a63503a7e /054string-equal.subx
parentc913d04dfa32c35509ba95ca809e7599fc6036f7 (diff)
downloadmu-d20fbf71c379b6f51a3edd57cc4a1d2ad37ed8e0.tar.gz
5948 - branching to named blocks
Diffstat (limited to '054string-equal.subx')
-rw-r--r--054string-equal.subx80
1 files changed, 61 insertions, 19 deletions
diff --git a/054string-equal.subx b/054string-equal.subx
index 10706302..dff7a485 100644
--- a/054string-equal.subx
+++ b/054string-equal.subx
@@ -16,10 +16,52 @@ Entry:  # run all tests
 string-equal?:  # s: (addr array byte), benchmark: (addr array byte) -> eax: boolean
     # pseudocode:
     #   if (s->length != benchmark->length) return false
+    #   return string-starts-with?(s, benchmark)
+    #
+    # . prologue
+    55/push-ebp
+    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+    # . save registers
+    51/push-ecx
+    56/push-esi
+    57/push-edi
+    # esi = s
+    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
+    # edi = benchmark
+    8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   0xc/disp8       .                 # copy *(ebp+12) to edi
+    # ecx = s->length
+    8b/copy                         0/mod/indirect  6/rm32/esi    .           .             .           1/r32/ecx   .               .                 # copy *esi to ecx
+$string-equal?:lengths:
+    # if (ecx != benchmark->length) return false
+    39/compare                      0/mod/indirect  7/rm32/edi    .           .             .           1/r32/ecx   .               .                 # compare *edi and ecx
+    b8/copy-to-eax  0/imm32/false
+    75/jump-if-!=  $string-equal?:end/disp8
+$string-equal?:contents:
+    # string-starts-with?(s, benchmark)
+    # . . push args
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+0xc)
+    ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
+    # . . call
+    e8/call  string-starts-with?/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+$string-equal?:end:
+    # . restore registers
+    5f/pop-to-edi
+    5e/pop-to-esi
+    59/pop-to-ecx
+    # . epilogue
+    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+    5d/pop-to-ebp
+    c3/return
+
+string-starts-with?:  # s: (addr array byte), benchmark: (addr array byte) -> eax: boolean
+    # pseudocode:
+    #   if (s->length < benchmark->length) return false
     #   currs = s->data
     #   currb = benchmark->data
-    #   maxs = &s->data[s->length]
-    #   while currs < maxs
+    #   maxb = &benchmark->data[benchmark->length]
+    #   while currb < maxb
     #     c1 = *currs
     #     c2 = *currb
     #     if (c1 != c2) return false
@@ -45,44 +87,44 @@ string-equal?:  # s: (addr array byte), benchmark: (addr array byte) -> eax: boo
     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
     # edi = benchmark
     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   0xc/disp8       .                 # copy *(ebp+12) to edi
-    # ecx = s->length
-    8b/copy                         0/mod/indirect  6/rm32/esi    .           .             .           1/r32/ecx   .               .                 # copy *esi to ecx
-$string-equal?:lengths:
-    # if (ecx != benchmark->length) return false
-    39/compare                      0/mod/indirect  7/rm32/edi    .           .             .           1/r32/ecx   .               .                 # compare *edi and ecx
-    75/jump-if-!=  $string-equal?:false/disp8
+    # var blen/ecx: int = benchmark->length
+    8b/copy                         0/mod/indirect  7/rm32/edi    .           .             .           1/r32/ecx   .               .                 # copy *edi to ecx
+$string-starts-with?:lengths:
+    # if (s->length < blen) return false
+    39/compare                      0/mod/indirect  6/rm32/esi    .           .             .           1/r32/ecx   .               .                 # compare *esi with ecx
+    7c/jump-if-<  $string-starts-with?:false/disp8
     # var currs/esi: (addr byte) = s->data
     81          0/subop/add         3/mod/direct    6/rm32/esi    .           .             .           .           .               4/imm32           # add to esi
-    # var maxs/ecx: (addr byte) = &s->data[s->length]
-    01/add                          3/mod/direct    1/rm32/ecx    .           .             .           6/r32/esi   .               .                 # add esi to ecx
     # var currb/edi: (addr byte) = benchmark->data
     81          0/subop/add         3/mod/direct    7/rm32/edi    .           .             .           .           .               4/imm32           # add to edi
+    # var maxb/ecx: (addr byte) = &benchmark->data[benchmark->length]
+    01/add                          3/mod/direct    1/rm32/ecx    .           .             .           7/r32/edi   .               .                 # add edi to ecx
     # var c1/eax: byte = 0
     31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
     # var c2/edx: byte = 0
     31/xor                          3/mod/direct    2/rm32/edx    .           .             .           2/r32/edx   .               .                 # clear edx
-$string-equal?:loop:
+$string-starts-with?:loop:
     # if (currs >= maxs) return true
-    39/compare                      3/mod/direct    6/rm32/esi    .           .             .           1/r32/ecx   .               .                 # compare esi with ecx
-    73/jump-if-addr>=  $string-equal?:true/disp8
+    39/compare                      3/mod/direct    7/rm32/edi    .           .             .           1/r32/ecx   .               .                 # compare edi with ecx
+    73/jump-if-addr>=  $string-starts-with?:true/disp8
     # c1 = *currs
     8a/copy-byte                    0/mod/indirect  6/rm32/esi    .           .             .           0/r32/AL    .               .                 # copy byte at *esi to AL
     # c2 = *currb
     8a/copy-byte                    0/mod/indirect  7/rm32/edi    .           .             .           2/r32/DL    .               .                 # copy byte at *edi to DL
     # if (c1 != c2) return false
     39/compare                      3/mod/direct    0/rm32/eax    .           .             .           2/r32/edx   .               .                 # compare eax and edx
-    75/jump-if-!=  $string-equal?:false/disp8
+    75/jump-if-!=  $string-starts-with?:false/disp8
     # ++currs
     46/increment-esi
     # ++currb
     47/increment-edi
-    eb/jump  $string-equal?:loop/disp8
-$string-equal?:true:
+    eb/jump  $string-starts-with?:loop/disp8
+$string-starts-with?:true:
     b8/copy-to-eax  1/imm32
-    eb/jump  $string-equal?:end/disp8
-$string-equal?:false:
+    eb/jump  $string-starts-with?:end/disp8
+$string-starts-with?:false:
     b8/copy-to-eax  0/imm32
-$string-equal?:end:
+$string-starts-with?:end:
     # . restore registers
     5f/pop-to-edi
     5e/pop-to-esi