about summary refs log tree commit diff stats
path: root/apps/pack.subx
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-06-20 00:50:36 -0700
committerKartik Agaram <vc@akkartik.com>2020-06-20 00:50:36 -0700
commit6131749762bfa71c7859170ead53bb1d5ffd2b4f (patch)
tree40c6050ae8e2515d7f7532da5ed0fd739bae2a4d /apps/pack.subx
parentd1ad96e0389b10e1a386004b3f4d46ac21544fa2 (diff)
downloadmu-6131749762bfa71c7859170ead53bb1d5ffd2b4f.tar.gz
6557 - fix a bug in pack.subx
I was shifting bitfields around based on their width rather than the width
of the field to their right.

Kinda shocking that I haven't used the scale bits until now. I've been
generating code that uses them in mu.subx tests, but apparently I haven't
actually _run_ any such code before.
Diffstat (limited to 'apps/pack.subx')
-rw-r--r--apps/pack.subx96
1 files changed, 94 insertions, 2 deletions
diff --git a/apps/pack.subx b/apps/pack.subx
index 60133ba4..5da27c08 100644
--- a/apps/pack.subx
+++ b/apps/pack.subx
@@ -2576,7 +2576,7 @@ emit-sib:  # line: (addr stream byte), out: (addr buffered-file)
     #       has-sib? = true
     #   if has-sib?
     #     var sib = scale & 0b11
-    #     sib <<= 2
+    #     sib <<= 3
     #     sib |= index & 0b111
     #     sib <<= 3
     #     sib |= base & 0b111
@@ -2804,7 +2804,7 @@ $emit-sib:calculate:
     # var sib/ebx: byte = scale & 0b11
     81          4/subop/and         3/mod/direct    3/rm32/ebx    .           .             .           .           .               3/imm32/0b11      # bitwise and of ebx
     # sib <<= 2
-    c1/shift    4/subop/left        3/mod/direct    3/rm32/ebx    .           .             .           .           .               2/imm8            # shift ebx left by 2 bits
+    c1/shift    4/subop/left        3/mod/direct    3/rm32/ebx    .           .             .           .           .               3/imm8            # shift ebx left by 3 bits
     # sib |= index & 0b111
     81          4/subop/and         3/mod/direct    7/rm32/edi    .           .             .           .           .               7/imm32/0b111     # bitwise and of edi
     09/or                           3/mod/direct    3/rm32/ebx    .           .             .           7/r32/edi   .               .                 # ebx = bitwise OR with edi
@@ -4905,6 +4905,98 @@ test-convert-instruction-emits-sib-byte:
     5d/pop-to-ebp
     c3/return
 
+test-convert-instruction-emits-scale:
+    # pack base, index and scale operands into SIB byte
+    # . prologue
+    55/push-ebp
+    89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+    # setup
+    # . clear-stream(_test-input-stream)
+    # . . push args
+    68/push  _test-input-stream/imm32
+    # . . call
+    e8/call  clear-stream/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+    # . clear-stream(_test-output-stream)
+    # . . push args
+    68/push  _test-output-stream/imm32
+    # . . call
+    e8/call  clear-stream/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+    # . clear-stream($_test-output-buffered-file->buffer)
+    # . . push args
+    68/push  $_test-output-buffered-file->buffer/imm32
+    # . . call
+    e8/call  clear-stream/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+    # initialize input
+    # . write(_test-input-stream, "8b/copy 0/mod 4/rm32 1/scale")
+    # . . push args
+    68/push  "8b/copy 0/mod 4/rm32 1/scale"/imm32
+    68/push  _test-input-stream/imm32
+    # . . call
+    e8/call  write/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+    # convert-instruction(_test-input-stream, _test-output-buffered-file)
+    # . . push args
+    68/push  _test-output-buffered-file/imm32
+    68/push  _test-input-stream/imm32
+    # . . call
+    e8/call  convert-instruction/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+    # check output
+    # . flush(_test-output-buffered-file)
+    # . . push args
+    68/push  _test-output-buffered-file/imm32
+    # . . call
+    e8/call  flush/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+#?     # dump output {{{
+#?     # . write(2/stderr, "^")
+#?     # . . push args
+#?     68/push  "^"/imm32
+#?     68/push  2/imm32/stderr
+#?     # . . call
+#?     e8/call  write/disp32
+#?     # . . discard args
+#?     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+#?     # . write-stream(2/stderr, _test-output-stream)
+#?     # . . push args
+#?     68/push  _test-output-stream/imm32
+#?     68/push  2/imm32/stderr
+#?     # . . call
+#?     e8/call  write-stream/disp32
+#?     # . . discard args
+#?     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+#?     # . write(2/stderr, "$\n")
+#?     # . . push args
+#?     68/push  "$\n"/imm32
+#?     68/push  2/imm32/stderr
+#?     # . . call
+#?     e8/call  write/disp32
+#?     # . . discard args
+#?     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+#?     # }}}
+    # . check-stream-equal(_test-output-stream, "8b 04 40  # 8b/copy 0/mod 4/rm32 1/scale", msg)
+    # . . push args
+    68/push  "F - test-convert-instruction-emits-scale"/imm32
+    68/push  "8b 04 40  # 8b/copy 0/mod 4/rm32 1/scale"/imm32
+    68/push  _test-output-stream/imm32
+    # . . call
+    e8/call  check-stream-equal/disp32
+    # . . discard args
+    81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+    # . epilogue
+    89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+    5d/pop-to-ebp
+    c3/return
+
 test-convert-instruction-emits-sib-byte-with-missing-base:
     # pack index and scale operands into SIB byte
     # . prologue