4a3fa51ffad9439228b74844de439f2d1d827151
[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   `(#xff #x75 ,(- 0 (* 4 n))))          ; pushl  0x<n>(%ebp)
46
47 (define (i386:push-accu)
48   `(#x50))                              ; push %eax
49
50 (define (i386:push-arg s t d)
51   (lambda (o)
52     (cond ((number? o)
53            `(#x68 ,@(int->bv32 o)))       ; push $<o>
54           ((pair? o) o)
55           ((procedure? o) (o s t d)))))
56
57 (define (i386:ret . rest)
58   (lambda (s t d)
59     `(
60       ,@(cond ((null? rest) '())
61               ((number? (car rest))
62                `(#xb8                     ; mov    $<>,%eax
63                  ,@(int->bv32 (car rest))))
64               ((pair? (car rest)) (car rest))
65               ((procedure? (car rest))
66                ((car rest) s t d)))
67     #xc9                                ; leave
68     #xc3                                ; ret
69     )))
70
71 (define (i386:accu->local n)
72   `(#x89 #x45 ,(- 0 (* 4 n))))          ; mov    ,%eax,-<0xn>(%ebp)
73
74 (define (i386:local->accu n)
75   `(#x8b #x45 ,(- 0 (* 4 n))))          ; mov    -<0xn>(%ebp),%eax
76
77 (define (i386:local->base n)
78   `(#x8b #x55 ,(- 0 (* 4 n))))          ; mov    -<0xn>(%ebp),%edx
79
80 (define (i386:mem-byte->accu)
81   '(#x01 #xd0                           ; add    %edx,%eax
82          #x0f #xb6 #x00))               ; movzbl (%eax),%eax
83
84 (define (i386:mem->accu)
85   '(#x01 #xd0                           ; add    %edx,%eax
86          #x8b #x00))                    ; mov    (%eax),%eax
87
88 (define (i386:value->accu v)
89   `(#xb8 ,@(int->bv32 v)))              ; mov    $<v>,%eax
90
91 (define (i386:local-add n v)
92   `(#x83 #x45 ,(- 0 (* 4 n)) ,v))       ; addl   $<v>,0x<n>(%ebp)
93     
94 (define (i386:local-assign n v)
95   `(#xc7 #x45 ,(- 0 (* 4 n))            ; movl   $<v>,0x<n>(%ebp)
96          ,@(int->bv32 v)))
97
98 (define (i386:local-test n v)
99   `(#x83 #x7d ,(- 0 (* 4 n)) ,v))       ; cmpl   $<v>,0x<n>(%ebp)
100
101 (define (i386:ret-local n)
102   `(
103     #x89 #x45 ,(- 0 (* 4 n))            ; mov    %eax,-0x<n>(%ebp)
104     ))
105
106 (define (i386:call s t d address . arguments)
107   (let* ((pushes (append-map (i386:push-arg s t d) (reverse arguments)))
108          (s (length pushes))
109          (n (length arguments)))
110    `(
111      ,@pushes                           ; push args
112      #xe8 ,@(int->bv32 (- address 5 s)) ; call relative
113      #x83 #xc4 ,(* n 4)                 ; add    $00,%esp
114      )))
115   
116 (define (i386:exit s t d)
117   `(
118     #x5b                                ; pop    %ebx
119     #x5b                                ; pop    %ebx
120     #xb8 #x01 #x00 #x00 #x00            ; mov    $0x1,%eax
121     #xcd #x80                           ; int    $0x80
122     ))
123
124 ;; (define (i386:_start s t d)
125 ;;   (let* ((prefix
126 ;;           `(
127 ;;             #x55                         ; push   %ebp
128 ;;             #x89 #xe5                    ; mov    %esp,%ebp
129       
130 ;;             ;;#x83 #xec #x10                 ; sub    $0x10,%esp -- 4 local vars
131             
132 ;;             #xe8 ,@(int->bv32 (- address 5 s)) ; call relative
133
134 ;;             #xb8 #x04 #x00 #x00 #x00     ; mov    $0x4,%eax
135 ;;             #xcd #x80                    ; int    $0x80
136       
137 ;;             #xc9                         ; leave
138 ;;             #xc3                         ; ret
139 ;;             ))
140 ;;          (text-list (text->list t))
141 ;;          (statement-offset (- (+ (length prefix) (length text-list))))
142 ;;          (address (+ t (function-offset "main" s))))))
143
144 (define (i386:write s t d)
145   `(
146     #x55                                ; push   %ebp
147     #x89 #xe5                           ; mov    %esp,%ebp
148
149     #x8b #x5d #x08                      ; mov    $0x8(%ebp),%ebx
150     #x8b #x4d #x0c                      ; mov    $0xc(%ebp),%ecx
151     #x8b #x55 #x10                      ; mov    $0x4(%ebp),%edx
152
153     #xb8 #x04 #x00 #x00 #x00            ; mov    $0x4,%eax
154     #xcd #x80                           ; int    $0x80
155
156     #xc9                                ; leave
157     #xc3                                ; ret
158     ))
159
160 (define (i386:jump n)
161   `(#xeb ,(if (>= n 0) n (- n 2))))     ; jmp <n>
162
163 (define (i386:jump-le n)
164   `(#x7e ,(if (>= n 0) n (- n 4))))     ; jle <n>
165
166 (define (i386:jump-nz n)
167   `(#x84 #xc0                           ; test   %al,%al
168     #x75 ,(if (>= n 0) n (- n 4))))     ; jne <n>
169
170 #!
171 int
172 strcmp (char const* a, char const* b)
173 {
174  while (*a && *b && *a == *b) {*a++;b++;
175                                }
176   return *a == *b;
177 }
178 08048150 <strcmp>:
179  8048150:       55                      push   %ebp
180  8048151:       89 e5                   mov    %esp,%ebp
181  8048153:       eb 0d                   jmp    8048162 <strcmp+0x12>
182
183 <body>
184  8048155:       8b 45 08                mov    0x8(%ebp),%eax
185  8048158:       83 c0 01                add    $0x1,%eax
186  804815b:       89 45 08                mov    %eax,0x8(%ebp)
187  804815e:       83 45 0c 01             addl   $0x1,0xc(%ebp)
188
189 <test>
190  8048162:       8b 45 08                mov    0x8(%ebp),%eax
191  8048165:       0f b6 00                movzbl (%eax),%eax
192  8048168:       84 c0                   test   %al,%al
193  804816a:       74 1a                   je     8048186 <strcmp+0x36>
194
195  804816c:       8b 45 0c                mov    0xc(%ebp),%eax
196  804816f:       0f b6 00                movzbl (%eax),%eax
197  8048172:       84 c0                   test   %al,%al
198  8048174:       74 10                   je     8048186 <strcmp+0x36>
199
200  8048176:       8b 45 08                mov    0x8(%ebp),%eax
201  8048179:       0f b6 10                movzbl (%eax),%edx
202  804817c:       8b 45 0c                mov    0xc(%ebp),%eax
203  804817f:       0f b6 00                movzbl (%eax),%eax
204  8048182:       38 c2                   cmp    %al,%dl
205  8048184:       74 cf                   je     8048155 <strcmp+0x5>
206
207 <done>
208  8048186:       8b 45 08                mov    0x8(%ebp),%eax
209  8048189:       0f b6 10                movzbl (%eax),%edx
210  804818c:       8b 45 0c                mov    0xc(%ebp),%eax
211  804818f:       0f b6 00                movzbl (%eax),%eax
212  8048192:       38 c2                   cmp    %al,%dl
213  8048194:       0f 94 c0                sete   %al
214  8048197:       0f b6 c0                movzbl %al,%eax
215  804819a:       5d                      pop    %ebp
216  804819b:       c3                      ret    
217 !#