.
[mu.git] / linux / 310copy-bytes.subx
blob2586a53fe4dab6af58a7d71eed2f303eadcd8aac
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     # var out/ecx: (handle array byte)
106     68/push 0/imm32
107     68/push 0/imm32
108     89/<- %ecx 4/r32/esp
109     #
110     (stream-to-array _test-input-stream %ecx)
111     (lookup *ecx *(ecx+4))  # => eax
112     (check-strings-equal %eax "bc")
113     # . epilogue
114     89/<- %esp 5/r32/ebp
115     5d/pop-to-ebp
116     c3/return
118 # like stream-to-array but ignore surrounding quotes
119 # we might do other stuff here later
120 unquote-stream-to-array:  # in: (addr stream _), out: (addr handle array _)
121     # . prologue
122     55/push-ebp
123     89/<- %ebp 4/r32/esp
124     # . save registers
125     50/push-eax
126     51/push-ecx
127     52/push-edx
128     56/push-esi
129     # esi = s
130     8b/-> *(ebp+8) 6/r32/esi
131     # var len/ecx: int = s->write - s->read - 2
132     8b/-> *esi 1/r32/ecx
133     2b/subtract *(esi+4) 1/r32/ecx
134     81 7/subop/compare %ecx 2/imm32
135     7c/jump-if-< $unquote-stream-to-array:end/disp8
136     81 5/subop/subtract %ecx 2/imm32
137     # allocate
138     (allocate-array Heap %ecx *(ebp+0xc))
139     # var in/edx: (addr byte) = s->data + s->read + 1
140     8b/-> *(esi+4) 2/r32/edx
141     8d/copy-address *(esi+edx+0xd) 2/r32/edx  # Stream-data + 1
142     # var dest/eax: (addr byte) = data for out
143     8b/-> *(ebp+0xc) 0/r32/eax
144     (lookup *eax *(eax+4))  # => eax
145     8d/copy-address *(eax+4) 0/r32/eax
146     #
147     (copy-bytes %edx %eax %ecx)
148 $unquote-stream-to-array:end:
149     # . restore registers
150     5e/pop-to-esi
151     5a/pop-to-edx
152     59/pop-to-ecx
153     58/pop-to-eax
154     # . epilogue
155     89/<- %esp 5/r32/ebp
156     5d/pop-to-ebp
157     c3/return