.
[mu.git] / 310copy-bytes.subx
blob64b8148adc959e7342bbd7e2b0b6f470f207b978
1 # Some helpers for copying non-overlapping regions of memory.
2 # Really only intended to be called from code generated by mu.subx.
4 == code
6 copy-bytes:  # src: (addr byte), dest: (addr byte), size: int
7     # pseudocode:
8     #   curr-src/esi = src
9     #   curr-dest/edi = dest
10     #   i/ecx = 0
11     #   while true
12     #     if (i >= size) break
13     #     *curr-dest = *curr-src
14     #     ++curr-src
15     #     ++curr-dest
16     #     ++i
17     #
18     # . prologue
19     55/push-ebp
20     89/<- %ebp 4/r32/esp
21     # . save registers
22     50/push-eax
23     51/push-ecx
24     52/push-edx
25     56/push-esi
26     57/push-edi
27     # curr-src/esi = src
28     8b/-> *(ebp+8) 6/r32/esi
29     # curr-dest/edi = dest
30     8b/-> *(ebp+0xc) 7/r32/edi
31     # var i/ecx: int = 0
32     b9/copy-to-ecx 0/imm32
33     # edx = size
34     8b/-> *(ebp+0x10) 2/r32/edx
35     {
36       # if (i >= size) break
37       39/compare %ecx 2/r32/edx
38       7d/jump-if->=  break/disp8
39       # *curr-dest = *curr-src
40       8a/byte-> *esi 0/r32/AL
41       88/byte<- *edi 0/r32/AL
42       # update
43       46/increment-esi
44       47/increment-edi
45       41/increment-ecx
46       eb/jump loop/disp8
47     }
48 $copy-bytes:end:
49     # . restore registers
50     5f/pop-to-edi
51     5e/pop-to-esi
52     5a/pop-to-edx
53     59/pop-to-ecx
54     58/pop-to-eax
55     # . epilogue
56     89/<- %esp 5/r32/ebp
57     5d/pop-to-ebp
58     c3/return
60 stream-to-array:  # in: (addr stream _), out: (addr handle array _)
61     # . prologue
62     55/push-ebp
63     89/<- %ebp 4/r32/esp
64     # . save registers
65     50/push-eax
66     51/push-ecx
67     52/push-edx
68     56/push-esi
69     # esi = s
70     8b/-> *(ebp+8) 6/r32/esi
71     # var len/ecx: int = s->write - s->read
72     8b/-> *esi 1/r32/ecx
73     2b/subtract *(esi+4) 1/r32/ecx
74     # allocate
75     (allocate-array Heap %ecx *(ebp+0xc))
76     # var in/edx: (addr byte) = s->data + s->read
77     8b/-> *(esi+4) 2/r32/edx
78     8d/copy-address *(esi+edx+0xc) 2/r32/edx
79     # var dest/eax: (addr byte) = data for out
80     8b/-> *(ebp+0xc) 0/r32/eax
81     (lookup *eax *(eax+4))  # => eax
82     8d/copy-address *(eax+4) 0/r32/eax
83     #
84     (copy-bytes %edx %eax %ecx)
85 $stream-to-array:end:
86     # . restore registers
87     5e/pop-to-esi
88     5a/pop-to-edx
89     59/pop-to-ecx
90     58/pop-to-eax
91     # . epilogue
92     89/<- %esp 5/r32/ebp
93     5d/pop-to-ebp
94     c3/return
96 test-stream-to-array:
97     # . prologue
98     55/push-ebp
99     89/<- %ebp 4/r32/esp
100     # setup
101     (clear-stream _test-input-stream)
102     (write _test-input-stream "abc")
103     # skip something
104     (read-byte _test-input-stream)  # => eax
105     8b/-> *$_test-input-stream->read 0/r32/eax
106     (check-ints-equal %eax 1 "F - test-stream-to-array/pre")
107     # var out/ecx: (handle array byte)
108     68/push 0/imm32
109     68/push 0/imm32
110     89/<- %ecx 4/r32/esp
111     #
112     (stream-to-array _test-input-stream %ecx)
113     (lookup *ecx *(ecx+4))  # => eax
114     (check-strings-equal %eax "bc" "F - test-stream-to-array")
115     8b/-> *$_test-input-stream->read 0/r32/eax
116     (check-ints-equal %eax 1 "F - test-stream-to-array/read-pointer-not-perturbed")
117     # . epilogue
118     89/<- %esp 5/r32/ebp
119     5d/pop-to-ebp
120     c3/return
122 # like stream-to-array but ignore surrounding quotes
123 # we might do other stuff here later
124 unquote-stream-to-array:  # in: (addr stream _), out: (addr handle array _)
125     # . prologue
126     55/push-ebp
127     89/<- %ebp 4/r32/esp
128     # . save registers
129     50/push-eax
130     51/push-ecx
131     52/push-edx
132     56/push-esi
133     # esi = s
134     8b/-> *(ebp+8) 6/r32/esi
135     # var len/ecx: int = s->write - s->read - 2
136     8b/-> *esi 1/r32/ecx
137     2b/subtract *(esi+4) 1/r32/ecx
138     81 7/subop/compare %ecx 2/imm32
139     7c/jump-if-< $unquote-stream-to-array:end/disp8
140     81 5/subop/subtract %ecx 2/imm32
141     # allocate
142     (allocate-array Heap %ecx *(ebp+0xc))
143     # var in/edx: (addr byte) = s->data + s->read + 1
144     8b/-> *(esi+4) 2/r32/edx
145     8d/copy-address *(esi+edx+0xd) 2/r32/edx  # Stream-data + 1
146     # var dest/eax: (addr byte) = data for out
147     8b/-> *(ebp+0xc) 0/r32/eax
148     (lookup *eax *(eax+4))  # => eax
149     8d/copy-address *(eax+4) 0/r32/eax
150     #
151     (copy-bytes %edx %eax %ecx)
152 $unquote-stream-to-array:end:
153     # . restore registers
154     5e/pop-to-esi
155     5a/pop-to-edx
156     59/pop-to-ecx
157     58/pop-to-eax
158     # . epilogue
159     89/<- %esp 5/r32/ebp
160     5d/pop-to-ebp
161     c3/return