about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2020-08-22 14:35:44 -0700
committerKartik Agaram <vc@akkartik.com>2020-08-22 14:35:44 -0700
commit15b9880136b6b4754a6e6498c81932e553246d9f (patch)
tree2ad3b055a2383ffbd980193310e0775b1d0c170c
parentdb894e7968808512392c46d62b2bee68b891db04 (diff)
downloadmu-15b9880136b6b4754a6e6498c81932e553246d9f.tar.gz
6727 - bugfix in a multiply instruction
Also more error-detection for this case all across the toolchain.
-rw-r--r--033check_operands.cc2
-rw-r--r--121new-stream.subx2
-rw-r--r--308allocate-array.subx5
-rwxr-xr-xapps/mubin388320 -> 388322 bytes
-rw-r--r--apps/mu.subx7
5 files changed, 10 insertions, 6 deletions
diff --git a/033check_operands.cc b/033check_operands.cc
index 28a7458e..f46176c7 100644
--- a/033check_operands.cc
+++ b/033check_operands.cc
@@ -379,7 +379,7 @@ void check_operands_modrm(const line& inst, const word& op) {
   check_operand_metadata_present(inst, "mod", op);
   check_operand_metadata_present(inst, "rm32", op);
   // no check for r32; some instructions don't use it; just assume it's 0 if missing
-  if (op.data == "81" || op.data == "8f" || op.data == "ff") {  // keep sync'd with 'help subop'
+  if (op.data == "81" || op.data == "8f" || op.data == "f7" || op.data == "ff") {  // keep sync'd with 'help subop'
     check_operand_metadata_present(inst, "subop", op);
     check_operand_metadata_absent(inst, "r32", op, "should be replaced by subop");
   }
diff --git a/121new-stream.subx b/121new-stream.subx
index e781ecd6..41d1c31b 100644
--- a/121new-stream.subx
+++ b/121new-stream.subx
@@ -17,7 +17,7 @@ new-stream:  # ad: (addr allocation-descriptor), length: int, elemsize: int, out
     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           0/r32/eax   0x10/disp8      .                 # copy *(ebp+16) to eax
     # . eax *= length
     31/xor                          3/mod/direct    2/rm32/edx    .           .             .           2/r32/edx   .               .                 # clear edx
-    f7          4/subop/multiply    1/mod/*+disp8   5/rm32/ebp    .           .                                     0xc/disp8       .                 # multiply *(ebp+12) into eax
+    f7          4/subop/multiply    1/mod/*+disp8   5/rm32/ebp    .           .                                     0xc/disp8       .                 # multiply *(ebp+12) into edx:eax
     # . if overflow abort
     81          7/subop/compare     3/mod/direct    2/rm32/edx    .           .             .           .           .               0/imm32           # compare edx
     75/jump-if-!=  $new-stream:abort/disp8
diff --git a/308allocate-array.subx b/308allocate-array.subx
index 01eb1dc3..2d3d1a9d 100644
--- a/308allocate-array.subx
+++ b/308allocate-array.subx
@@ -6,12 +6,15 @@ allocate-array2:  # ad: (addr allocation-descriptor), array-len: int, elem-size:
     89/<- %ebp 4/r32/esp
     # . save registers
     50/push-eax
+    52/push-edx
     #
     8b/-> *(ebp+0xc) 0/r32/eax
-    f7 4/subop/multiply-into 0/r32/eax *(ebp+0x10)
+    f7 4/subop/multiply-into-eax-edx *(ebp+0x10)
+    # TODO: check edx for overflow
     (allocate-array *(ebp+8) %eax *(ebp+0x14))
 $allocate-array2:end:
     # . restore registers
+    5a/pop-to-edx
     58/pop-to-eax
     # . epilogue
     89/<- %esp 5/r32/ebp
diff --git a/apps/mu b/apps/mu
index 8bf88983..0dceb721 100755
--- a/apps/mu
+++ b/apps/mu
Binary files differdiff --git a/apps/mu.subx b/apps/mu.subx
index c7076627..f673045a 100644
--- a/apps/mu.subx
+++ b/apps/mu.subx
@@ -14409,8 +14409,9 @@ size-of-array:  # a: (addr type-tree) -> result/eax: int
     8b/-> *(eax+8) 1/r32/ecx  # Type-tree-value-size
     # return 4 + array-size * size-of(elem-type)
     (size-of-type-id-as-array-element %edx)  # => eax
-    f7 4/subop/multiply-into-eax %ecx
+    f7 4/subop/multiply-into-edx-eax %ecx
     05/add-to-eax 4/imm32  # for array size
+    # TODO: check edx for overflow
 $size-of-array:end:
     # . restore registers
     5a/pop-to-edx
@@ -16549,7 +16550,7 @@ $translate-mu-index-stmt-with-array-in-register:emit-literal-index:
       89/<- %edx 0/r32/eax
       # offset = idx-value * array-element-size(base->type)
       (array-element-size %ebx *(ebp+0x10) *(ebp+0x14))  # => eax
-      f7 4/subop/multiply-into-eax %edx  # clobbers edx
+      f7 4/subop/multiply-into-edx-eax %edx  # clobbers edx
       # offset += 4 for array size
       05/add-to-eax 4/imm32
       # TODO: check edx for overflow
@@ -16666,7 +16667,7 @@ $translate-mu-index-stmt-with-array-on-stack:emit-literal-index:
       89/<- %edx 0/r32/eax
       # offset = idx-value * array-element-size(base)
       (array-element-size %ecx *(ebp+0x10) *(ebp+0x14))  # => eax
-      f7 4/subop/multiply-into-eax %edx  # clobbers edx
+      f7 4/subop/multiply-into-edx-eax %edx  # clobbers edx
       # offset += base->offset
       03/add *(ecx+0x14) 0/r32/eax  # Var-offset
       # offset += 4 for array size