mescc: Have micro-mes use strcmp to print help.
[mes.git] / module / mes / libc-i386.mes
1 ;;; -*-scheme-*-
2
3 ;;; Mes --- Maxwell Equations of Software
4 ;;; Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
5 ;;;
6 ;;; This file is part of Mes.
7 ;;;
8 ;;; Mes is free software; you can redistribute it and/or modify it
9 ;;; under the terms of the GNU General Public License as published by
10 ;;; the Free Software Foundation; either version 3 of the License, or (at
11 ;;; your option) any later version.
12 ;;;
13 ;;; Mes is distributed in the hope that it will be useful, but
14 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;;; GNU General Public License for more details.
17 ;;;
18 ;;; You should have received a copy of the GNU General Public License
19 ;;; along with Mes.  If not, see <http://www.gnu.org/licenses/>.
20
21 ;;; Commentary:
22
23 ;;; libc-i386.mes defines C library routines
24
25 ;;; Code:
26
27 (define (i386:function-preamble)
28   '(#x55                                ; push   %ebp
29     #x89 #xe5))                         ; mov    %esp,%ebp
30
31 (define (i386:function-locals)
32   '(#x83 #xec #x10))               ; sub    $0x10,%esp -- 4 local vars
33
34 ;; (define (i386:formal i n)
35 ;;   (case i
36 ;;     ((0) (list #x8b #x5d (* (- n 2) 4)))       ; mov    $00(%ebp),%ebx
37 ;;     ((1) (list #x8b #x4d (* (- n 3) 4)))    ; mov    $00(%ebp),%ecx
38 ;;     ((2) (list #x8b #x55 (* (- n 4) 4)))    ; mov    $00(%ebp),%edx
39 ;;     ((3) (list #x8b #x45 (* (- n 5) 4)))))  ; mov    $00(%ebp),%eax FIXME
40
41 (define (i386:ref-global o)
42   `(#x68 ,@(int->bv32 o)))               ; push  $0x<o>
43
44 (define (i386:ref-local n)
45   (or n rl)
46   `(#xff #x75 ,(- 0 (* 4 n))))          ; pushl  0x<n>(%ebp)
47
48 (define (i386:push-accu)
49   `(#x50))                              ; push %eax
50
51 (define (i386:push-arg f g t d)
52   (lambda (o)
53     (cond ((number? o)
54            `(#x68 ,@(int->bv32 o)))       ; push $<o>
55           ((pair? o) o)
56           ((procedure? o) (o f g t d)))))
57
58 (define (i386:ret . rest)
59   (lambda (f g t d)
60     `(
61       ,@(cond ((null? rest) '())
62               ((number? (car rest))
63                `(#xb8                     ; mov    $<>,%eax
64                  ,@(int->bv32 (car rest))))
65               ((pair? (car rest)) (car rest))
66               ((procedure? (car rest))
67                ((car rest) f g t d)))
68     #xc9                                ; leave
69     #xc3                                ; ret
70     )))
71
72 (define (i386:accu->local n)
73   (or n al)
74   `(#x89 #x45 ,(- 0 (* 4 n))))          ; mov    ,%eax,-<0xn>(%ebp)
75
76 (define (i386:accu-zero?)
77   `(#x85 #xc0))                         ; cmpl   %eax,%eax
78
79 (define (i386:local->accu n)
80   (or n la)
81   `(#x8b #x45 ,(- 0 (* 4 n))))          ; mov    -<0xn>(%ebp),%eax
82
83 (define (i386:local->base n)
84   (or n lb)
85   `(#x8b #x55 ,(- 0 (* 4 n))))          ; mov    -<0xn>(%ebp),%edx
86
87 (define (i386:mem-byte->accu)
88   '(#x01 #xd0                           ; add    %edx,%eax
89          #x0f #xb6 #x00))               ; movzbl (%eax),%eax
90
91 (define (i386:Xmem-byte->accu)
92   '(#x0f #xb6 #x00))                    ; movzbl (%eax),%eax
93
94 (define (i386:Xmem-byte->base)
95   '(#x0f #xb6 #x10))                    ; movzbl (%eax),%edx
96
97 (define (i386:mem->accu)
98   '(#x01 #xd0                           ; add    %edx,%eax
99          #x8b #x00))                    ; mov    (%eax),%eax
100
101 (define (i386:value->accu v)
102   `(#xb8 ,@(int->bv32 v)))              ; mov    $<v>,%eax
103
104 (define (i386:local-add n v)
105   (or n ladd)
106   `(#x83 #x45 ,(- 0 (* 4 n)) ,v))       ; addl   $<v>,0x<n>(%ebp)
107     
108 (define (i386:local-assign n v)
109   (or n lassign)
110   `(#xc7 #x45 ,(- 0 (* 4 n))            ; movl   $<v>,0x<n>(%ebp)
111          ,@(int->bv32 v)))
112
113 (define (i386:local-test n v)
114   (or n lt)
115   `(#x83 #x7d ,(- 0 (* 4 n)) ,v))       ; cmpl   $<v>,0x<n>(%ebp)
116
117 (define (i386:ret-local n)
118   (or n rl)
119   `(
120     #x89 #x45 ,(- 0 (* 4 n))            ; mov    %eax,-0x<n>(%ebp)
121     ))
122
123 (define (i386:call f g t d address . arguments)
124   (let* ((pushes (append-map (i386:push-arg f g t d) (reverse arguments)))
125          (s (length pushes))
126          (n (length arguments)))
127    `(
128      ,@pushes                           ; push args
129      #xe8 ,@(int->bv32 (- address 5 s)) ; call relative
130      #x83 #xc4 ,(* n 4)                 ; add    $00,%esp
131      )))
132   
133 (define (i386:exit f g t d)
134   `(
135     #x5b                                ; pop    %ebx
136     #x5b                                ; pop    %ebx
137     #xb8 #x01 #x00 #x00 #x00            ; mov    $0x1,%eax
138     #xcd #x80                           ; int    $0x80
139     ))
140
141 ;; (define (i386:_start f g t d)
142 ;;   (let* ((prefix
143 ;;           `(
144 ;;             #x55                         ; push   %ebp
145 ;;             #x89 #xe5                    ; mov    %esp,%ebp
146       
147 ;;             ;;#x83 #xec #x10                 ; sub    $0x10,%esp -- 4 local vars
148             
149 ;;             #xe8 ,@(int->bv32 (- address 5 s)) ; call relative
150
151 ;;             #xb8 #x04 #x00 #x00 #x00     ; mov    $0x4,%eax
152 ;;             #xcd #x80                    ; int    $0x80
153       
154 ;;             #xc9                         ; leave
155 ;;             #xc3                         ; ret
156 ;;             ))
157 ;;          (text-list (text->list t))
158 ;;          (statement-offset (- (+ (length prefix) (length text-list))))
159 ;;          (address (+ t (function-offset "main" s))))))
160
161 (define (i386:write f g t d)
162   `(
163     #x55                                ; push   %ebp
164     #x89 #xe5                           ; mov    %esp,%ebp
165
166     #x8b #x5d #x08                      ; mov    $0x8(%ebp),%ebx
167     #x8b #x4d #x0c                      ; mov    $0xc(%ebp),%ecx
168     #x8b #x55 #x10                      ; mov    $0x4(%ebp),%edx
169
170     #xb8 #x04 #x00 #x00 #x00            ; mov    $0x4,%eax
171     #xcd #x80                           ; int    $0x80
172
173     #xc9                                ; leave
174     #xc3                                ; ret
175     ))
176
177 (define (i386:jump n)
178   `(#xeb ,(if (>= n 0) n (- n 2))))     ; jmp <n>
179
180 (define (i386:jump-le n)
181   `(#x7e ,(if (>= n 0) n (- n 4))))     ; jle <n>
182
183 (define (i386:jump-byte-nz n)
184   `(#x84 #xc0                           ; test   %al,%al
185     #x75 ,(if (>= n 0) n (- n 4))))     ; jne <n>
186
187 (define (i386:jump-nz n)
188   `(#x85 #xc0                           ; test   %eax,%eax
189     #x75 ,(if (>= n 0) n (- n 4))))     ; jne <n>
190
191 (define (i386:jump-byte-z n)
192   `(#x84 #xc0                           ; test   %al,%al
193     #x74 ,(if (>= n 0) n (- n 4))))     ; jne <n>
194
195 (define (i386:test-byte-base)
196   `(#x38 #xc2))                         ; cmp    %al,%dl
197
198 (define (i386:Xjump-byte-z n)
199   `(#x74 ,(if (>= n 0) n (- n 2))))     ; je <n>
200
201 (define (i386:sub-byte-base)
202   `(#x28 #xd0))                         ; sub    %dl,%al
203
204 ;;28 d0                 sub    %dl,%al
205 ;;28 c2                 sub    %al,%dl
206 ;;29 d0                 sub    %edx,%eax
207 ;;29 c2                 sub    %eax,%edx
208
209 #!
210 int
211 strcmp (char const* a, char const* b)
212 {
213  while (*a && *b && *a == *b)
214    {
215      a++;b++;
216    }
217   return *a == *b;
218 }
219 08048150 <strcmp>:
220  8048150:       55                      push   %ebp
221  8048151:       89 e5                   mov    %esp,%ebp
222
223  8048153:       eb 08                   jmp    804815d <strcmp+0xd>
224
225 <body>
226  8048155:       83 45 08 01             addl   $0x1,0x8(%ebp)
227  8048159:       83 45 0c 01             addl   $0x1,0xc(%ebp)
228
229 <test>
230  804815d:       8b 45 08                mov    0x8(%ebp),%eax
231  8048160:       0f b6 00                movzbl (%eax),%eax
232  8048163:       84 c0                   test   %al,%al
233  8048165:       74 1a                   je     8048181 <strcmp+0x31>
234
235  8048167:       8b 45 0c                mov    0xc(%ebp),%eax
236  804816a:       0f b6 00                movzbl (%eax),%eax
237  804816d:       84 c0                   test   %al,%al
238  804816f:       74 10                   je     8048181 <strcmp+0x31>
239
240  8048171:       8b 45 08                mov    0x8(%ebp),%eax
241  8048174:       0f b6 10                movzbl (%eax),%edx
242  8048177:       8b 45 0c                mov    0xc(%ebp),%eax
243  804817a:       0f b6 00                movzbl (%eax),%eax
244  804817d:       38 c2                   cmp    %al,%dl
245  804817f:       74 d4                   je     8048155 <strcmp+0x5>
246
247 <exit>
248  8048181:       8b 45 08                mov    0x8(%ebp),%eax
249  8048184:       0f b6 00                movzbl (%eax),%eax
250  8048187:       0f be d0                movsbl %al,%edx
251
252  804818a:       8b 45 0c                mov    0xc(%ebp),%eax
253  804818d:       0f b6 00                movzbl (%eax),%eax
254  8048190:       0f be c0                movsbl %al,%eax
255
256  8048193:       29 c2                   sub    %eax,%edx
257  8048195:       89 d0                   mov    %edx,%eax
258
259  8048197:       5d                      pop    %ebp
260  8048198:       c3                      ret    
261 !#