about summary refs log tree commit diff stats
path: root/subx/054string-equal.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-07-27 16:01:55 -0700
committerKartik Agaram <vc@akkartik.com>2019-07-27 17:47:59 -0700
commit6e1eeeebfb453fa7c871869c19375ce60fbd7413 (patch)
tree539c4a3fdf1756ae79770d5c4aaf6366f1d1525e /subx/054string-equal.subx
parent8846a7f85cc04b77b2fe8a67b6d317723437b00c (diff)
downloadmu-6e1eeeebfb453fa7c871869c19375ce60fbd7413.tar.gz
5485 - promote SubX to top-level
Diffstat (limited to 'subx/054string-equal.subx')
-rw-r--r--subx/054string-equal.subx230
1 files changed, 0 insertions, 230 deletions
diff --git a/subx/054string-equal.subx b/subx/054string-equal.subx
deleted file mode 100644
index 9784e2ad..00000000
--- a/subx/054string-equal.subx
+++ /dev/null
@@ -1,230 +0,0 @@
-# Comparing 'regular' length-prefixed strings.
-
-== code
-#   instruction                     effective address                                                   register    displacement    immediate
-# . op          subop               mod             rm32          base        index         scale       r32
-# . 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes
-
-Entry:  # run all tests
-#?     e8/call test-compare-equal-strings/disp32
-    e8/call  run-tests/disp32  # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'.
-    # syscall(exit, Num-test-failures)
-    8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/EBX   Num-test-failures/disp32          # copy *Num-test-failures to EBX
-    b8/copy-to-EAX  1/imm32/exit
-    cd/syscall  0x80/imm8
-
-string-equal?:  # s : (address string), benchmark : (address string) -> EAX : boolean
-    # pseudocode:
-    #   if (s->length != benchmark->length) return false
-    #   currs = s->data
-    #   currb = benchmark->data
-    #   maxs = s->data + s->length
-    #   while currs < maxs
-    #     c1 = *currs
-    #     c2 = *currb
-    #     if (c1 != c2) return false
-    #     ++currs, ++currb
-    #   return true
-    #
-    # registers:
-    #   currs: ESI
-    #   maxs: ECX
-    #   currb: EDI
-    #   c1: EAX
-    #   c2: EBX
-    #
-    # . prolog
-    55/push-EBP
-    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # . save registers
-    51/push-ECX
-    52/push-EDX
-    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
-    75/jump-if-not-equal  $string-equal?:false/disp8
-    # currs/ESI = s->data
-    81          0/subop/add         3/mod/direct    6/rm32/ESI    .           .             .           .           .               4/imm32           # add to ESI
-    # maxs/ECX = s->data + s->length
-    01/add                          3/mod/direct    1/rm32/ECX    .           .             .           6/r32/ESI   .               .                 # add ESI to ECX
-    # currb/EDI = benchmark->data
-    81          0/subop/add         3/mod/direct    7/rm32/EDI    .           .             .           .           .               4/imm32           # add to EDI
-    # c1/EAX = c2/EDX = 0
-    31/xor                          3/mod/direct    0/rm32/EAX    .           .             .           0/r32/EAX   .               .                 # clear EAX
-    31/xor                          3/mod/direct    2/rm32/EDX    .           .             .           2/r32/EDX   .               .                 # clear EDX
-$string-equal?:loop:
-    # if (currs >= maxs) return true
-    39/compare                      3/mod/direct    6/rm32/ESI    .           .             .           1/r32/ECX   .               .                 # compare ESI with ECX
-    73/jump-if-greater-or-equal-unsigned  $string-equal?: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-not-equal  $string-equal?:false/disp8
-    # ++currs
-    46/increment-ESI
-    # ++currb
-    47/increment-EDI
-    eb/jump  $string-equal?:loop/disp8
-$string-equal?:true:
-    b8/copy-to-EAX  1/imm32
-    eb/jump  $string-equal?:end/disp8
-$string-equal?:false:
-    b8/copy-to-EAX  0/imm32
-$string-equal?:end:
-    # . restore registers
-    5f/pop-to-EDI
-    5e/pop-to-ESI
-    5a/pop-to-EDX
-    59/pop-to-ECX
-    # . epilog
-    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
-    5d/pop-to-EBP
-    c3/return
-
-# - tests
-
-test-compare-empty-with-empty-string:
-    # EAX = string-equal?("", "")
-    # . . push args
-    68/push  ""/imm32
-    68/push  ""/imm32
-    # . . call
-    e8/call  string-equal?/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # check-ints-equal(EAX, 1, msg)
-    # . . push args
-    68/push  "F - test-compare-empty-with-empty-string"/imm32
-    68/push  1/imm32/true
-    50/push-EAX
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-    c3/return
-
-test-compare-empty-with-non-empty-string:  # also checks length-mismatch code path
-    # EAX = string-equal?("", "Abc")
-    # . . push args
-    68/push  "Abc"/imm32
-    68/push  ""/imm32
-    # . . call
-    e8/call  string-equal?/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # check-ints-equal(EAX, 0, msg)
-    # . . push args
-    68/push  "F - test-compare-empty-with-non-empty-string"/imm32
-    68/push  0/imm32/false
-    50/push-EAX
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-    c3/return
-
-test-compare-equal-strings:
-    # EAX = string-equal?("Abc", "Abc")
-    # . . push args
-    68/push  "Abc"/imm32
-    68/push  "Abc"/imm32
-    # . . call
-    e8/call  string-equal?/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # check-ints-equal(EAX, 1, msg)
-    # . . push args
-    68/push  "F - test-compare-equal-strings"/imm32
-    68/push  1/imm32/true
-    50/push-EAX
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-    c3/return
-
-test-compare-inequal-strings-equal-lengths:
-    # EAX = string-equal?("Abc", "Adc")
-    # . . push args
-    68/push  "Adc"/imm32
-    68/push  "Abc"/imm32
-    # . . call
-    e8/call  string-equal?/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # check-ints-equal(EAX, 0, msg)
-    # . . push args
-    68/push  "F - test-compare-inequal-strings-equal-lengths"/imm32
-    68/push  0/imm32/false
-    50/push-EAX
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-    c3/return
-
-# helper for later tests
-check-string-equal:  # s : (address string), expected : (address string), msg : (address string)
-    # . prolog
-    55/push-EBP
-    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
-    # . save registers
-    50/push-EAX
-    # EAX = string-equal?(s, expected)
-    # . . push args
-    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0xc/disp8       .                 # push *(EBP+12)
-    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
-    # . . call
-    e8/call  string-equal?/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # check-ints-equal(EAX, 1, msg)
-    # . . push args
-    ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           0x10/disp8      .                 # push *(EBP+16)
-    68/push  1/imm32
-    50/push-EAX
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-$check-string-equal:end:
-    # . restore registers
-    58/pop-to-EAX
-    # . epilog
-    89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
-    5d/pop-to-EBP
-    c3/return
-
-# test the helper
-test-check-string-equal:
-    # check-string-equal?("Abc", "Abc")
-    # . . push args
-    68/push  "Abc"/imm32
-    68/push  "Abc"/imm32
-    # . . call
-    e8/call  check-string-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
-    # check-ints-equal(EAX, 1, msg)
-    # . . push args
-    68/push  "F - test-check-string-equal"/imm32
-    68/push  0/imm32/false
-    50/push-EAX
-    # . . call
-    e8/call  check-ints-equal/disp32
-    # . . discard args
-    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
-    c3/return
-
-# . . vim:nowrap:textwidth=0
a>