From 6131749762bfa71c7859170ead53bb1d5ffd2b4f Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sat, 20 Jun 2020 00:50:36 -0700 Subject: 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. --- apps/pack | Bin 56707 -> 56971 bytes apps/pack.subx | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 94 insertions(+), 2 deletions(-) (limited to 'apps') diff --git a/apps/pack b/apps/pack index e0ff769a..bcd5af94 100755 Binary files a/apps/pack and b/apps/pack differ 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 -- cgit 1.4.1-2-gfad0