7286 - mu.subx: isolate bytes from previous values
This commit is contained in:
parent
c165b0be5a
commit
125bfde435
79
apps/mu.subx
79
apps/mu.subx
|
@ -3620,19 +3620,21 @@ test-convert-function-with-byte-operations:
|
|||
(check-next-stream-line-equal _test-output-stream " ff 6/subop/push %ecx" "F - test-convert-function-with-byte-operations/8")
|
||||
(check-next-stream-line-equal _test-output-stream " b9/copy-to-ecx 0/imm32" "F - test-convert-function-with-byte-operations/9")
|
||||
(check-next-stream-line-equal _test-output-stream " 8a/byte-> %eax 0x00000001/r32" "F - test-convert-function-with-byte-operations/10")
|
||||
(check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-function-with-byte-operations/11")
|
||||
(check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 0/imm32" "F - test-convert-function-with-byte-operations/12")
|
||||
(check-next-stream-line-equal _test-output-stream " 8a/byte-> *edx 0x00000001/r32" "F - test-convert-function-with-byte-operations/13")
|
||||
(check-next-stream-line-equal _test-output-stream " 88/byte<- *edx 0x00000000/r32" "F - test-convert-function-with-byte-operations/14")
|
||||
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-function-with-byte-operations/15")
|
||||
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-byte-operations/16")
|
||||
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-byte-operations/17")
|
||||
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-byte-operations/18")
|
||||
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-byte-operations/19")
|
||||
(check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-byte-operations/20")
|
||||
(check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-byte-operations/21")
|
||||
(check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-byte-operations/22")
|
||||
(check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-byte-operations/23")
|
||||
(check-next-stream-line-equal _test-output-stream " 81 4/subop/and %ecx 0xff/imm32" "F - test-convert-function-with-byte-operations/11")
|
||||
(check-next-stream-line-equal _test-output-stream " ff 6/subop/push %edx" "F - test-convert-function-with-byte-operations/12")
|
||||
(check-next-stream-line-equal _test-output-stream " ba/copy-to-edx 0/imm32" "F - test-convert-function-with-byte-operations/13")
|
||||
(check-next-stream-line-equal _test-output-stream " 8a/byte-> *edx 0x00000001/r32" "F - test-convert-function-with-byte-operations/14")
|
||||
(check-next-stream-line-equal _test-output-stream " 81 4/subop/and %ecx 0xff/imm32" "F - test-convert-function-with-byte-operations/15")
|
||||
(check-next-stream-line-equal _test-output-stream " 88/byte<- *edx 0x00000000/r32" "F - test-convert-function-with-byte-operations/16")
|
||||
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %edx" "F - test-convert-function-with-byte-operations/17")
|
||||
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %ecx" "F - test-convert-function-with-byte-operations/18")
|
||||
(check-next-stream-line-equal _test-output-stream " 8f 0/subop/pop %eax" "F - test-convert-function-with-byte-operations/19")
|
||||
(check-next-stream-line-equal _test-output-stream " }" "F - test-convert-function-with-byte-operations/20")
|
||||
(check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:" "F - test-convert-function-with-byte-operations/21")
|
||||
(check-next-stream-line-equal _test-output-stream " # . epilogue" "F - test-convert-function-with-byte-operations/22")
|
||||
(check-next-stream-line-equal _test-output-stream " 89/<- %esp 5/r32/ebp" "F - test-convert-function-with-byte-operations/23")
|
||||
(check-next-stream-line-equal _test-output-stream " 5d/pop-to-ebp" "F - test-convert-function-with-byte-operations/24")
|
||||
(check-next-stream-line-equal _test-output-stream " c3/return" "F - test-convert-function-with-byte-operations/25")
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
|
@ -28302,6 +28304,16 @@ emit-subx-stmt: # out: (addr buffered-file), stmt: (addr stmt), primitives: (ad
|
|||
8b/-> *(ebp+0xc) 1/r32/ecx
|
||||
(lookup *(ecx+4) *(ecx+8)) # Stmt1-operation Stmt1-operation => eax
|
||||
89/<- %ecx 0/r32/eax
|
||||
# copy byte (can be a primitive except we need to emit a second instruction)
|
||||
{
|
||||
# if (!string-equal?(stmt->operation, "copy-byte")) break
|
||||
(string-equal? %ecx "copy-byte") # => eax
|
||||
3d/compare-eax-and 0/imm32
|
||||
0f 84/jump-if-= break/disp32
|
||||
(translate-mu-copy-byte-stmt *(ebp+8) *(ebp+0xc) *(ebp+0x18) *(ebp+0x1c))
|
||||
e9/jump $emit-subx-stmt:end/disp32
|
||||
}
|
||||
# copy-byte-to can be a primitive; writes to memory don't need to clear surrounding bytes
|
||||
# array size
|
||||
{
|
||||
# if (!string-equal?(stmt->operation, "length")) break
|
||||
|
@ -28751,6 +28763,47 @@ $emit-divide-by-shift-right:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
translate-mu-copy-byte-stmt: # out: (addr buffered-file), stmt: (addr stmt), err: (addr buffered-file), ed: (addr exit-descriptor)
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/<- %ebp 4/r32/esp
|
||||
# . save registers
|
||||
50/push-eax
|
||||
56/push-esi
|
||||
# esi = stmt
|
||||
8b/-> *(ebp+0xc) 6/r32/esi
|
||||
#
|
||||
(emit-indent *(ebp+8) *Curr-block-depth)
|
||||
(write-buffered *(ebp+8) "8a/byte->")
|
||||
# emit stmt->inouts[0]
|
||||
(lookup *(esi+0xc) *(esi+0x10)) # Stmt1-inouts Stmt1-inouts => eax
|
||||
(emit-subx-var-as-rm32 *(ebp+8) %eax)
|
||||
# emit /r32 for stmt->outputs[0]->register
|
||||
(lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
|
||||
(lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
|
||||
(lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
|
||||
(maybe-get Mu-registers %eax 0xc) # => eax: (addr register-index)
|
||||
(write-buffered *(ebp+8) Space)
|
||||
(write-int32-hex-buffered *(ebp+8) *eax)
|
||||
(write-buffered *(ebp+8) "/r32\n")
|
||||
# clear rest of register
|
||||
(emit-indent *(ebp+8) *Curr-block-depth)
|
||||
(write-buffered *(ebp+8) "81 4/subop/and %")
|
||||
8b/-> *(ebp+0xc) 0/r32/eax
|
||||
(lookup *(esi+0x14) *(esi+0x18)) # Stmt1-outputs Stmt1-outputs => eax
|
||||
(lookup *eax *(eax+4)) # Stmt-var-value Stmt-var-value => eax
|
||||
(lookup *(eax+0x18) *(eax+0x1c)) # Var-register Var-register => eax
|
||||
(write-buffered *(ebp+8) %eax)
|
||||
(write-buffered *(ebp+8) " 0xff/imm32\n")
|
||||
$translate-mu-copy-byte-stmt:end:
|
||||
# . restore registers
|
||||
5e/pop-to-esi
|
||||
58/pop-to-eax
|
||||
# . epilogue
|
||||
89/<- %esp 5/r32/ebp
|
||||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
# a little different from other translate- functions; notice the extra 'fn' argument
|
||||
translate-mu-index-stmt: # out: (addr buffered-file), stmt: (addr stmt), fn: (addr function), err: (addr buffered-file), ed: (addr exit-descriptor)
|
||||
# . prologue
|
||||
|
|
3
mu.md
3
mu.md
|
@ -685,7 +685,8 @@ enforce type- and memory-safety, I was forced to carve out a few exceptions:
|
|||
* the `length` instruction on arrays, for translating the array size in bytes
|
||||
into the number of elements.
|
||||
* the `lookup` instruction on handles, for validating fat-pointer metadata
|
||||
* `var` instructions, for initializing memory
|
||||
* `var` instructions, to initialize memory
|
||||
* byte copies, to initialize memory
|
||||
|
||||
If you're curious, [the compiler summary page](http://akkartik.github.io/mu/html/mu_instructions.html)
|
||||
has the complete nitty-gritty on how each instruction is implemented. Including
|
||||
|
|
|
@ -115,7 +115,9 @@ copy-to var, n => "c7 0/subop/copy *(ebp+" var.stack-offset "
|
|||
copy-to *var/reg, n => "c7 0/subop/copy *" reg " " n "/imm32"
|
||||
|
||||
var/reg <- copy-byte var2/reg2 => "8a/byte-> %" reg2 " " reg "/r32"
|
||||
"81 4/subop/and %" reg " 0xff/imm32"
|
||||
var/reg <- copy-byte *var2/reg2 => "8a/byte-> *" reg2 " " reg "/r32"
|
||||
"81 4/subop/and %" reg " 0xff/imm32"
|
||||
copy-byte-to *var1/reg1, var2/reg2 => "88/byte<- *" reg1 " " reg2 "/r32"
|
||||
|
||||
compare var1, var2/reg2 => "39/compare *(ebp+" var1.stack-offset ") " reg2 "/r32"
|
||||
|
|
Loading…
Reference in New Issue