about summary refs log tree commit diff stats
path: root/subx/apps/subx-common.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-07-07 23:56:23 -0700
committerKartik Agaram <vc@akkartik.com>2019-07-07 23:56:23 -0700
commit195d62f167d51b43ef7dc564899427ee63328c97 (patch)
treee7c1ae0c83f9a15de58231d9b79745d88db534ad /subx/apps/subx-common.subx
parent23bc3650e0d4d7ccc8a8976cb085d202c7d1bc39 (diff)
downloadmu-195d62f167d51b43ef7dc564899427ee63328c97.tar.gz
build `num-bytes`
Diffstat (limited to 'subx/apps/subx-common.subx')
-rw-r--r--subx/apps/subx-common.subx64
1 files changed, 62 insertions, 2 deletions
diff --git a/subx/apps/subx-common.subx b/subx/apps/subx-common.subx
index d9f4e34c..ef1a6f93 100644
--- a/subx/apps/subx-common.subx
+++ b/subx/apps/subx-common.subx
@@ -1136,7 +1136,7 @@ test-has-metadata-multiple-false:
     5d/pop-to-EBP
     c3/return
 
-compute-width: # word : (address array byte)
+compute-width: # word : (address array byte) -> EAX : int
     # . prolog
     55/push-EBP
     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
@@ -1198,7 +1198,7 @@ compute-width: # word : (address array byte)
     # else: return 1
     b8/copy-to-EAX  1/imm32
 $compute-width:end:
-    # . discard locals
+    # . reclaim locals
     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
     # . restore registers
     59/pop-to-ECX
@@ -1322,6 +1322,66 @@ $test-compute-width:no-metadata:
     5d/pop-to-EBP
     c3/return
 
+compute-width-of-slice: # s : (address slice) -> EAX : int
+    # . prolog
+    55/push-EBP
+    89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+    # . save registers
+    51/push-ECX
+    # ECX = s
+    8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           1/r32/ECX   8/disp8         .                 # copy *(EBP+8) to ECX
+    # if has-metadata?(word, "imm32") or has-metadata?(word, "disp32"): return 4
+    # . EAX = has-metadata?(word, "imm32")
+    68/push  "imm32"/imm32
+    51/push-ECX
+    e8/call  has-metadata?/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # . if EAX: return 4
+    3d/compare-EAX-and  1/imm32
+    b8/copy-to-EAX  4/imm32         # ZF is set, so we can overwrite EAX now
+    74/jump-if-equal  $compute-width-of-slice:end/disp8
+    # . has-metadata?(word, "disp32")
+    68/push  "disp32"/imm32
+    51/push-ECX
+    e8/call  has-metadata?/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # . if EAX: return 4
+    3d/compare-EAX-and  1/imm32
+    b8/copy-to-EAX  4/imm32         # ZF is set, so we can overwrite EAX now
+    74/jump-if-equal  $compute-width-of-slice:end/disp8
+    # if has-metadata?(word, "imm16") or has-metadata?(word, "disp16"): return 2
+    # . has-metadata?(word, "imm16")
+    68/push  "imm16"/imm32
+    51/push-ECX
+    e8/call  has-metadata?/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # . if EAX: return 2
+    3d/compare-EAX-and  1/imm32
+    b8/copy-to-EAX  2/imm32         # ZF is set, so we can overwrite EAX now
+    74/jump-if-equal  $compute-width-of-slice:end/disp8
+    # . has-metadata?(word, "disp16")
+    68/push  "disp16"/imm32
+    51/push-ECX
+    e8/call  has-metadata?/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+    # . if EAX: return 2
+    3d/compare-EAX-and  1/imm32
+    b8/copy-to-EAX  2/imm32         # ZF is set, so we can overwrite EAX now
+    74/jump-if-equal  $compute-width-of-slice:end/disp8
+    # else: return 1
+    b8/copy-to-EAX  1/imm32
+$compute-width-of-slice:end:
+    # . restore registers
+    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
+
 is-label?: # word : (address slice) -> EAX : boolean
     # . prolog
     55/push-EBP