diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-08-22 14:35:44 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-08-22 14:35:44 -0700 |
commit | 15b9880136b6b4754a6e6498c81932e553246d9f (patch) | |
tree | 2ad3b055a2383ffbd980193310e0775b1d0c170c | |
parent | db894e7968808512392c46d62b2bee68b891db04 (diff) | |
download | mu-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.cc | 2 | ||||
-rw-r--r-- | 121new-stream.subx | 2 | ||||
-rw-r--r-- | 308allocate-array.subx | 5 | ||||
-rwxr-xr-x | apps/mu | bin | 388320 -> 388322 bytes | |||
-rw-r--r-- | apps/mu.subx | 7 |
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 |