mescc: Formals, local variables.
[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-arg s t d)
48   (lambda (o)
49     (cond ((number? o)
50            `(#x68 ,@(int->bv32 o)))       ; push $<o>
51           ((pair? o) o)
52           ((procedure? o) (o s t d)))))
53
54 (define (i386:ret . rest)
55   (lambda (s t d)
56     `(
57       ,@(cond ((null? rest) '())
58               ((number? (car rest))
59                `(#xb8                     ; mov    $<>,%eax
60                  ,@(int->bv32 (car rest))))
61               ((pair? (car rest)) (car rest))
62               ((procedure? (car rest))
63                ((car rest) s t d)))
64     #xc9                                ; leave
65     #xc3                                ; ret
66     )))
67
68 (define (i386:local->accu n)
69   `(#x8b #x45 ,(- 0 (* 4 n))))          ; mov    -<0xn>(%ebp),%eax
70
71 (define (i386:local->base n)
72   `(#x8b #x55 ,(- 0 (* 4 n))))          ; mov    -<0xn>(%ebp),%edx
73
74 (define (i386:mem-byte->accu)
75   '(#x01 #xd0                           ; add    %edx,%eax
76          #x0f #xb6 #x00))               ; movzbl (%eax),%eax
77
78 (define (i386:local-add n v)
79   `(#x83 #x45 ,(- 0 (* 4 n)) ,v))       ; addl   $<v>,0x<n>(%ebp)
80     
81 (define (i386:local-assign n v)
82   `(#xc7 #x45 ,(- 0 (* 4 n))            ; movl   $<v>,0x<n>(%ebp)
83          ,@(int->bv32 v)))
84
85 (define (i386:ret-local n)
86   `(
87     #x89 #x45 ,(- 0 (* 4 n))            ; mov    %eax,-0x<n>(%ebp)
88     ))
89
90 (define (i386:call s t d address . arguments)
91   (let* ((pushes (append-map (i386:push-arg s t d) arguments))
92          (s (length pushes))
93          (n (length arguments)))
94    `(
95      ,@pushes                           ; push args
96      #xe8 ,@(int->bv32 (- address 5 s)) ; call relative
97      #x83 #xc4 ,(* n 4)                 ; add    $00,%esp
98      )))
99   
100 (define (i386:exit s t d)
101   `(
102     #x5b                                ; pop    %ebx
103     #x5b                                ; pop    %ebx
104     #xb8 #x01 #x00 #x00 #x00            ; mov    $0x1,%eax
105     #xcd #x80                           ; int    $0x80
106     ))
107
108 (define (i386:write s t d)
109   `(
110     #x55                                ; push   %ebp
111     #x89 #xe5                           ; mov    %esp,%ebp
112
113     #x8b #x5d #x10                      ; mov    $0x8(%ebp),%ebx
114     #x8b #x4d #x0c                      ; mov    $0xc(%ebp),%ecx
115     #x8b #x55 #x08                      ; mov    $0x4(%ebp),%edx
116
117     #xb8 #x04 #x00 #x00 #x00            ; mov    $0x4,%eax
118     #xcd #x80                           ; int    $0x80
119
120     #xc9                                ; leave
121     #xc3                                ; ret
122     ))
123
124 (define (i386:jump n)
125   `(#xeb ,(if (>= n 0) n (- n 2))))     ; jmp <n>
126
127 (define (i386:test-jump n)
128   `(#x84 #xc0                           ; test   %al,%al
129     #x75 ,(if (>= n 0) n (- n 4))))     ; jne <n>