mescc: Refactor libc.

* GNUmakefile (mini-mes): Add include.
* mlibc.c: New file: libc bits for GNUC -nostdlib.
* mstart.c: New file: _start for GNUC -nostdlib.
* scaffold/cons-mes.c: Remove GNUC libc bits.
* scaffold/m.c: Likewise.
* scaffold/mini-mes.c: Likewise.
* scaffold/t.c: Likewise.
* scaffold/tiny-mes.c: Litkewise.
* module/language/c99/compiler.mes (libc, i386:libc): Remove.
* module/language/c99/compiler.scm
* module/mes/libc-i386.mes: Remove assembly bits.
  (_start): New function.
* module/mes/libc-i386.scm: Export it, remove assembly exports.
* module/mes/as-i386.mes: New file: assembly bits from libc-i386.mes.
* module/mes/as-i386.scm: New file: export them.
* module/mes/libc.mes (libc,_start): New functions from compiler.mes.
* module/mes/libc.scm: Export them.
This commit is contained in:
Jan Nieuwenhuizen 2017-04-02 12:29:09 +02:00
parent 124352e087
commit 4e12e14b85
19 changed files with 1201 additions and 1970 deletions

View file

@ -120,38 +120,38 @@ mini-mes: mini-mes.h mini-mes.i mini-mes.environment.i mini-mes.symbols.i
mini-mes: GNUmakefile
mini-mes: doc/examples/mini-mes.c
rm -f $@
gcc -nostdlib --std=gnu99 -m32 -g -I. -o $@ '-DVERSION="0.4"' $<
gcc -nostdlib -I. --std=gnu99 -m32 -g -I. -o $@ '-DVERSION="0.4"' $<
chmod +x $@
cons-mes: scaffold/cons-mes.c GNUmakefile
rm -f $@
gcc -nostdlib --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
gcc -nostdlib -I. --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
chmod +x $@
tiny-mes: scaffold/tiny-mes.c GNUmakefile
rm -f $@
gcc -nostdlib --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
gcc -nostdlib -I. --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
chmod +x $@
m: scaffold/m.c GNUmakefile
rm -f $@
gcc -nostdlib --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
gcc -nostdlib -I. --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
# gcc --std=gnu99 -g -o $@ '-DVERSION="0.4"' $<
chmod +x $@
micro-mes: scaffold/micro-mes.c GNUmakefile
rm -f $@
gcc -nostdlib --std=gnu99 -m32 -o $@ '-DVERSION="0.4"' $<
gcc -nostdlib -I. --std=gnu99 -m32 -o $@ '-DVERSION="0.4"' $<
chmod +x $@
main: doc/examples/main.c GNUmakefile
rm -f $@
gcc -nostdlib --std=gnu99 -m32 -o $@ '-DVERSION="0.4"' $<
gcc -nostdlib -I. --std=gnu99 -m32 -o $@ '-DVERSION="0.4"' $<
chmod +x $@
t: scaffold/t.c GNUmakefile
rm -f $@
gcc -nostdlib --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
gcc -nostdlib -I. --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
chmod +x $@
MAIN_C:=doc/examples/main.c

View file

@ -19,65 +19,7 @@
*/
#if __GNUC__
void
exit (int code)
{
asm (
"movl %0,%%ebx\n\t"
"movl $1,%%eax\n\t"
"int $0x80"
: // no outputs "=" (r)
: "" (code)
);
// not reached
exit (0);
}
void
write (int fd, char const* s, int n)
{
int r;
//syscall (SYS_write, fd, s, n));
asm (
"mov %0,%%ebx\n\t"
"mov %1,%%ecx\n\t"
"mov %2,%%edx\n\t"
"mov $0x4, %%eax\n\t"
"int $0x80\n\t"
: // no outputs "=" (r)
: "" (fd), "" (s), "" (n)
: "eax", "ebx", "ecx", "edx"
);
}
#define STDOUT 1
typedef long size_t;
size_t
strlen (char const* s)
{
int i = 0;
while (s[i]) i++;
return i;
}
int
puts (char const* s)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
int i = strlen (s);
write (1, s, i);
return 0;
}
int
strcmp (char const* a, char const* b)
{
while (*a && *b && *a == *b) {a++;b++;}
return *a - *b;
}
#include "mlibc.c"
#endif
int
@ -90,27 +32,5 @@ main (int argc, char *argv[])
}
#if __GNUC__
void
_start ()
{
// int r=main ();
// exit (r);
int r;
asm (
"mov %%ebp,%%eax\n\t"
"addl $8,%%eax\n\t"
"push %%eax\n\t"
"mov %%ebp,%%eax\n\t"
"addl $4,%%eax\n\t"
"movzbl (%%eax),%%eax\n\t"
"push %%eax\n\t"
"call main\n\t"
"movl %%eax,%0\n\t"
: "=r" (r)
: //no inputs "" (&main)
);
exit (r);
}
#include "mstart.c"
#endif

230
mlibc.c Normal file
View file

@ -0,0 +1,230 @@
/* -*-comment-start: "//";comment-end:""-*-
* Mes --- Maxwell Equations of Software
* Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
*
* This file is part of Mes.
*
* Mes is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or (at
* your option) any later version.
*
* Mes is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
*/
#if __GNUC__
int g_stdin = 0;
typedef long size_t;
void *malloc (size_t i);
int open (char const *s, int mode);
int read (int fd, void* buf, size_t n);
void write (int fd, char const* s, int n);
void
exit (int code)
{
asm (
"movl %0,%%ebx\n\t"
"movl $1,%%eax\n\t"
"int $0x80"
: // no outputs "=" (r)
: "" (code)
);
// not reached
exit (0);
}
char const*
getenv (char const* p)
{
return 0;
}
int
read (int fd, void* buf, size_t n)
{
int r;
//syscall (SYS_write, fd, s, n));
asm (
"movl %1,%%ebx\n\t"
"movl %2,%%ecx\n\t"
"movl %3,%%edx\n\t"
"movl $0x3,%%eax\n\t"
"int $0x80\n\t"
"mov %%eax,%0\n\t"
: "=r" (r)
: "" (fd), "" (buf), "" (n)
: "eax", "ebx", "ecx", "edx"
);
return r;
}
int
open (char const *s, int mode)
{
int r;
//syscall (SYS_open, mode));
asm (
"mov %1,%%ebx\n\t"
"mov %2,%%ecx\n\t"
"mov $0x5,%%eax\n\t"
"int $0x80\n\t"
"mov %%eax,%0\n\t"
: "=r" (r)
: "" (s), "" (mode)
: "eax", "ebx", "ecx"
);
return r;
}
int puts (char const*);
char const* itoa (int);
int
getchar ()
{
char c;
int r = read (g_stdin, &c, 1);
if (r < 1) return -1;
int i = c;
if (i < 0) i += 256;
return i;
}
void
write (int fd, char const* s, int n)
{
int r;
//syscall (SYS_write, fd, s, n));
asm (
"mov %0,%%ebx\n\t"
"mov %1,%%ecx\n\t"
"mov %2,%%edx\n\t"
"mov $0x4, %%eax\n\t"
"int $0x80\n\t"
: // no outputs "=" (r)
: "" (fd), "" (s), "" (n)
: "eax", "ebx", "ecx", "edx"
);
}
int
putchar (int c)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
write (1, (char*)&c, 1);
return 0;
}
void *
malloc (size_t size)
{
int *n;
int len = size + sizeof (size);
//n = mmap (0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 );
*n = len;
return (void*)(n+1);
}
void
free (void *p)
{
int *n = (int*)p-1;
//munmap ((void*)p, *n);
}
#define EOF -1
#define STDIN 0
#define STDOUT 1
#define STDERR 2
size_t
strlen (char const* s)
{
int i = 0;
while (s[i]) i++;
return i;
}
int
strcmp (char const* a, char const* b)
{
while (*a && *b && *a == *b) {a++;b++;}
return *a - *b;
}
int
eputs (char const* s)
{
//int i = write (STDERR, s, strlen (s));
int i = strlen (s);
write (2, s, i);
return 0;
}
int
fputs (char const* s, int fd)
{
//int i = write (fd, s, strlen (s));
int i = strlen (s);
write (fd, s, i);
return 0;
}
int
puts (char const* s)
{
//int i = write (STDOUT, s, strlen (s));
int i = strlen (s);
write (1, s, i);
return 0;
}
char itoa_buf[10];
char const*
itoa (int x)
{
//static char itoa_buf[10];
//char *p = buf+9;
char *p = itoa_buf;
p += 9;
*p-- = 0;
//int sign = x < 0;
int sign;
sign = x < 0;
if (sign)
x = -x;
do
{
*p-- = '0' + (x % 10);
x = x / 10;
} while (x);
if (sign)
*p-- = '-';
return p+1;
}
void
assert_fail (char* s)
{
eputs ("assert fail: ");
eputs (s);
eputs ("\n");
*((int*)0) = 0;
}
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
#endif

View file

@ -57,22 +57,6 @@
(define (.name o)
(cadr o))
;; (define (.statement o)
;; (match o
;; (('function name signature statement) statement)
;; (_ #f)))
;; (define (statement->data o)
;; (match o
;; (('call 'puts ('arguments string)) (string->list string))
;; (_ '())))
;; (define (statement->text o)
;; (match o
;; (('call 'puts ('arguments string)) (list (lambda (data) (i386:puts data (string-length string)))))
;; (('return code) (list (lambda (data) (i386:exit code))))
;; (_ '())))
(define (.statement o)
(and (pair? o)
(eq? (car o) 'function)

View file

@ -25,8 +25,6 @@
;;; Code:
;;(define barf #f)
(cond-expand
(guile-2
(set-port-encoding! (current-output-port) "ISO-8859-1"))
@ -36,7 +34,8 @@
(mes-use-module (mes elf-util))
(mes-use-module (mes pmatch))
(mes-use-module (mes elf))
(mes-use-module (mes libc-i386))
(mes-use-module (mes as-i386))
(mes-use-module (mes libc))
(mes-use-module (mes optargs))))
(define (logf port string . rest)
@ -363,8 +362,20 @@ _)))))
(abs-declr (pointer)))
,cast)
((expr->arg info) cast))
(_
(format (current-error-port) "SKIP: expr->arg=~s\n" o)
;; (stderr "catch: expr->arg=~s\n" o)
(let* ((info ((expr->accu info) o))
(text (.text info)))
(clone info
#:text (append text
(list (lambda (f g ta t d)
(append
(i386:accu-zero?)
(i386:push-accu))))))))
(_
(stderr "SKIP: expr->arg=~s\n" o)
barf
0)))))
@ -767,20 +778,33 @@ _)))))
(accu ((expr->accu empty) a))
(base ((expr->base empty) b)))
(clone info #:text
(append text
(append text ;;FIXME:empty
(.text accu)
(.text base)
(list (lambda (f g ta t d)
(i386:accu%base)))))))
;; FIXME: c/p ast->info
((eq ,a ,b)
(let* ((base ((expr->base info) a))
(empty (clone base #:text '()))
(accu ((expr->accu empty) b)))
(clone info #:text
(append (.text base)
(list (lambda (f g ta t d)
(i386:push-base)))
(.text accu)
(i386:pop-accu)
(list (lambda (f g ta t d)
(i386:sub-base)))))))
;; FIXME: c/p ast->info
((lt ,a ,b)
(let* ((base ((expr->base info) a))
(empty (clone base #:text '()))
(accu ((expr->accu empty) b)))
(clone info #:text
(append text
(.text base)
(append (.text base)
(.text accu)
(list (lambda (f g ta t d)
(i386:base-sub)))))))
@ -1187,7 +1211,7 @@ _)))))
(locals (cons (make-local name type pointer id) locals)))
locals))
;;(stderr "\n ast->info=~s\n" o)
;; (stderr "\n ast->info=~s\n" o)
;; (stderr " globals[~a=>~a]: ~a\n" (length globals) (length (append-map cdr globals)) (map (lambda (s) (if (string? s) (string-delete #\newline s))) (map car globals)))
;; (stderr " text=~a\n" text)
;; (stderr " info=~a\n" info)
@ -2325,155 +2349,6 @@ _)))))
(if (null? elements) info
(loop (cdr elements) ((ast->info info) (car elements)))))))
(define _start
(let* ((argc-argv
(string-append ".byte"
" 0x89 0xe8" ; mov %ebp,%eax
" 0x83 0xc0 0x08" ; add $0x8,%eax
" 0x50" ; push %eax
" 0x89 0xe8" ; mov %ebp,%eax
" 0x83 0xc0 0x04" ; add $0x4,%eax
" 0x0f 0xb6 0x00" ; movzbl (%eax),%eax
" 0x50" ; push %eax
))
(ast (with-input-from-string
(string-append "int _start () {int i;asm(\"" argc-argv "\");i=main ();exit (i);}")
parse-c99)))
ast))
(define strlen
(let* ((ast (with-input-from-string
"
int
strlen (char const* s)
{
int i = 0;
while (s[i]) i++;
return i;
}
"
;;paredit:"
parse-c99)))
ast))
(define getchar
(let* ((ast (with-input-from-string
"
int g_stdin;
int
getchar ()
{
char c;
int r = read (g_stdin, &c, 1);
//int r = read (0, &c, 1);
if (r < 1) return -1;
return c;
}
"
;;paredit:"
parse-c99)))
ast))
(define putchar
(let* ((ast (with-input-from-string
"
int
putchar (int c)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
write (1, (char*)&c, 1);
return 0;
}
"
;;paredit:"
parse-c99)))
ast))
(define eputs
(let* ((ast (with-input-from-string
"
int
eputs (char const* s)
{
//write (STDERR, s, strlen (s));
//write (2, s, strlen (s));
int i = strlen (s);
write (2, s, i);
return 0;
}
"
;;paredit:"
parse-c99)))
ast))
(define fputs
(let* ((ast (with-input-from-string
"
int
fputs (char const* s, int fd)
{
int i = strlen (s);
write (fd, s, i);
return 0;
}
"
;;paredit:"
parse-c99)))
ast))
(define puts
(let* ((ast (with-input-from-string
"
int
puts (char const* s)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
int i = strlen (s);
write (1, s, i);
return 0;
}
"
;;paredit:"
parse-c99)))
ast))
(define strcmp
(let* ((ast (with-input-from-string
"
int
strcmp (char const* a, char const* b)
{
while (*a && *b && *a == *b)
{
a++;b++;
}
return *a - *b;
}
"
;;paredit:"
parse-c99)))
ast))
(define i386:libc
(list
(cons "exit" (list i386:exit))
(cons "open" (list i386:open))
(cons "read" (list i386:read))
(cons "write" (list i386:write))))
(define libc
(list
strlen
getchar
putchar
eputs
fputs
puts
strcmp))
(define (compile)
(let* ((ast (mescc))
(info (make <info>

View file

@ -29,7 +29,9 @@
#:use-module (ice-9 pretty-print)
#:use-module (mes elf)
#:use-module (mes elf-util)
#:use-module (mes as-i386)
#:use-module (mes libc-i386)
#:use-module (mes libc)
#:use-module (nyacc lang c99 parser)
#:export (compile))

418
module/mes/as-i386.mes Normal file
View file

@ -0,0 +1,418 @@
;;; -*-scheme-*-
;;; Mes --- Maxwell Equations of Software
;;; Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of Mes.
;;;
;;; Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with Mes. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; libc-i386.mes defines i386 assembly
;;; Code:
(cond-expand
(guile-2)
(guile)
(mes
(mes-use-module (mes elf))))
(define (i386:function-preamble)
'(#x55 ; push %ebp
#x89 #xe5)) ; mov %esp,%ebp
;; (define (i386:function-locals)
;; '(#x83 #xec #x20)) ; sub $0x10,%esp -- 8 local vars
(define (i386:function-locals)
'(#x83 #xec #x40)) ; sub $0x10,%esp -- 16 local vars
(define (i386:push-global-address o)
(or o push-global-address)
`(#x68 ,@(int->bv32 o))) ; push $0x<o>
(define (i386:push-global o)
(or o push-global)
`(#xa1 ,@(int->bv32 o) ; mov 0x804a000,%eax
#x50)) ; push %eax
(define (i386:push-local n)
(or n push-local)
`(#xff #x75 ,(- 0 (* 4 n)))) ; pushl 0x<n>(%ebp)
(define (i386:push-local-address n)
(or n push-local-address)
`(#x8d #x45 ,(- 0 (* 4 n)) ; lea 0x<n>(%ebp),%eax
#x50)) ; push %eax
(define (i386:push-local-de-ref n)
(or n push-local-de-ref)
`(#x8b #x45 ,(- 0 (* 4 n)) ; mov -0x<n>(%ebp),%eax
#x0f #xb6 #x00 ; movzbl (%eax),%eax
;;#x0f #xbe #xc0 ; movsbl %al,%eax ***FIXME BYTE****
#x50)) ; push %eax
(define (i386:pop-accu)
'(#x58)) ; pop %eax
(define (i386:push-accu)
'(#x50)) ; push %eax
(define (i386:pop-base)
'(#x5a)) ; pop %eax
(define (i386:push-base)
'(#x52)) ; push %eax
(define (i386:ret)
'(#xc9 ; leave
#xc3)) ; ret
(define (i386:accu->base)
'(#x89 #xc2)) ; mov %eax,%edx
(define (i386:accu->base-address)
'(#x89 #x02)) ; mov %eax,%(edx)
(define (i386:byte-accu->base-address)
'(#x88 #x02)) ; mov %al,%(edx)
(define (i386:accu->base-address+n n)
(or n accu->base-address+n)
`(#x89 #x42 ,n)) ; mov %eax,$0x<n>%(edx)
(define (i386:accu->local n)
(or n accu->local)
`(#x89 #x45 ,(- 0 (* 4 n)))) ; mov %eax,-<0xn>(%ebp)
(define (i386:base->local n)
(or n base->local)
`(#x89 #x55 ,(- 0 (* 4 n)))) ; mov %edx,-<0xn>(%ebp)
(define (i386:base->global n)
(or n base->global)
`(#x89 #x15 ,@(int->bv32 n))) ; mov %edx,0x0
(define (i386:accu->global n)
(or n accu->global)
`(#xa3 ,@(int->bv32 n))) ; mov %eax,0x0
(define (i386:accu->global-address n)
(or n accu->global-address)
`(#x8b #x15 ,@(int->bv32 n) ; mov 0x<n>,%edx
#x89 #x02 )) ; mov %eax,(%edx)
(define (i386:accu-zero?)
'(#x85 #xc0)) ; cmpl %eax,%eax
(define (i386:accu-non-zero?)
(append '(#x85 #xc0) ; cmpl %eax,%eax
(i386:xor-zf)))
(define (i386:accu-shl n)
(or n accu:shl n)
`(#xc1 #xe0 ,n)) ; shl $0x8,%eax
(define (i386:accu+accu)
'(#x01 #xc0)) ; add %eax,%eax
(define (i386:accu+base)
`(#x01 #xd0)) ; add %edx,%eax
(define (i386:accu+value v)
(or v accu+value)
`(#x05 ,@(int->bv32 v))) ; add %eax,%eax
(define (i386:accu-base)
`(#x29 #xd0)) ; sub %edx,%eax
(define (i386:accu/base)
'(#x86 #xd3 ; mov %edx,%ebx
#x31 #xd2 ; xor %edx,%edx
#xf7 #xf3)) ; div %ebx
(define (i386:accu%base)
'(#x86 #xd3 ; mov %edx,%ebx
#x31 #xd2 ; xor %edx,%edx
#xf7 #xf3 ; div %ebx
#x89 #xd0)) ; mov %edx,%eax
(define (i386:base->accu)
'(#x89 #xd0)) ; mov %edx,%eax
(define (i386:local->accu n)
(or n local->accu)
`(#x8b #x45 ,(- 0 (* 4 n)))) ; mov -<0xn>(%ebp),%eax
(define (i386:local-address->accu n)
(or n ladd)
`(#x8d #x45 ,(- 0 (* 4 n)))) ; lea 0x<n>(%ebp),%eax
(define (i386:local-ptr->accu n)
(or n local-ptr->accu)
`(#x89 #xe8 ; mov %ebp,%eax
#x83 #xc0 ,(- 0 (* 4 n)))) ; add $0x<n>,%eax
(define (i386:byte-local->accu n)
(or n byte-local->accu)
`(#x0f #xb6 #x45 ,(- 0 (* 4 n)))) ; movzbl 0x<n>(%ebp),%eax
(define (i386:local->base n)
(or n local->base)
`(#x8b #x55 ,(- 0 (* 4 n)))) ; mov -<0xn>(%ebp),%edx
(define (i386:local-address->base n) ;; DE-REF
(or n local-address->base)
`(#x8d #x55 ,(- 0 (* 4 n)))) ; lea 0x<n>(%ebp),%edx
(define (i386:local-ptr->base n)
(or n local-ptr->base)
`(#x89 #xea ; mov %ebp,%edx
#x83 #xc2 ,(- 0 (* 4 n)))) ; add $0x<n>,%edx
(define (i386:global->base n)
(or n global->base)
`(#xba ,@(int->bv32 n))) ; mov $<n>,%edx
(define (i386:global-address->accu n)
(or n global-address->accu)
`(#xa1 ,@(int->bv32 n))) ; mov 0x<n>,%eax
(define (i386:global-address->base n)
(or n global-address->base)
`(#x8b #x15 ,@(int->bv32 n))) ; mov 0x<n>,%edx
(define (i386:byte-base-mem->accu)
'(#x01 #xd0 ; add %edx,%eax
#x0f #xb6 #x00)) ; movzbl (%eax),%eax
(define (i386:byte-mem->accu)
'(#x0f #xb6 #x00)) ; movzbl (%eax),%eax
(define (i386:byte-mem->base)
'(#x0f #xb6 #x10)) ; movzbl (%eax),%edx
(define (i386:base-mem->accu)
'(#x01 #xd0 ; add %edx,%eax
#x8b #x00)) ; mov (%eax),%eax
(define (i386:mem->accu)
'(#x8b #x00)) ; mov (%eax),%eax
(define (i386:mem+n->accu n)
`(#x8b #x40 ,n)) ; mov 0x<n>(%eax),%eax
(define (i386:base-mem+n->accu n)
(or n base-mem+n->accu)
`(#x01 #xd0 ; add %edx,%eax
#x8b #x40 ,n)) ; mov <n>(%eax),%eax
(define (i386:value->accu v)
(or v urg:value->accu)
`(#xb8 ,@(int->bv32 v))) ; mov $<v>,%eax
(define (i386:value->accu-address v)
`(#xc7 #x00 ,@(int->bv32 v))) ; movl $0x<v>,(%eax)
(define (i386:value->accu-address+n n v)
(or v urg:value->accu-address+n)
`(#xc7 #x40 ,n ,@(int->bv32 v))) ; movl $<v>,0x<n>(%eax)
(define (i386:base->accu-address)
'(#x89 #x10)) ; mov %edx,(%eax)
(define (i386:base-address->accu-address)
'(#x8b #x0a ; mov (%edx),%ecx
#x89 #x08)) ; mov %ecx,(%eax)
(define (i386:accu+n n)
`(#x83 #xc0 ,n)) ; add $0x00,%eax
(define (i386:base+n n)
`(#x83 #xc2 ,n)) ; add $0x00,%edx
(define (i386:byte-base->accu-address)
'(#x88 #x10)) ; mov %dl,(%eax)
(define (i386:byte-base->accu-address+n n)
(or n byte-base->accu-address+n)
`(#x88 #x50 ,n)) ; mov %dl,0x<n>(%eax)
(define (i386:value->base v)
(or v urg:value->base)
`(#xba ,@(int->bv32 v))) ; mov $<v>,%edx
(define (i386:local-add n v)
(or n urg:local-add)
`(#x83 #x45 ,(- 0 (* 4 n)) ,v)) ; addl $<v>,0x<n>(%ebp)
(define (i386:global-add n v)
(or n urg:global-add)
`(#x83 #x05 ,@(int->bv32 n) ,v)) ; addl $<v>,0x<n>
(define (i386:global->accu o)
(or o urg:global->accu)
`(#xb8 ,@(int->bv32 o))) ; mov $<>,%eax
(define (i386:value->global n v)
(or n value->global)
`(#xc7 #x05 ,@(int->bv32 n) ; movl $<v>,(<n>)
,@(int->bv32 v)))
(define (i386:value->local n v)
(or n value->local)
`(#xc7 #x45 ,(- 0 (* 4 n)) ; movl $<v>,0x<n>(%ebp)
,@(int->bv32 v)))
(define (i386:local-test n v)
(or n local-test)
`(#x83 #x7d ,(- 0 (* 4 n)) ,v)) ; cmpl $<v>,0x<n>(%ebp)
(define (i386:call f g ta t d address n)
(or address urg:call)
`(#xe8 ,@(int->bv32 (- address 5)) ; call relative $00
#x83 #xc4 ,(* n 4))) ; add $00,%esp
(define (i386:call-accu f g ta t d n)
`(,@(i386:push-accu)
,@(i386:pop-accu)
#xff #xd0 ; call *%eax
#x83 #xc4 ,(* n 4))) ; add $00,%esp
(define (i386:accu-not)
`(#x0f #x94 #xc0 ; sete %al
#x0f #xb6 #xc0)) ; movzbl %al,%eax
(define (i386:xor-accu v)
(or n urg:xor-accu)
`(#x35 ,@(int->bv32 v))) ;xor $0xff,%eax
(define (i386:xor-zf)
'(#x9f ; lahf
#x80 #xf4 #x40 ; xor $0x40,%ah
#x9e)) ; sahf
(define (i386:accu-cmp-value v)
`(#x83 #xf8 ,v)) ; cmp $<v>,%eax
(define (i386:accu-test)
'(#x85 #xc0)) ; test %eax,%eax
(define (i386:Xjump n)
(or n urg:Xjump)
`(#xe9 ,@(int->bv32 (if (>= n 0) n (- n 5))))) ; jmp . + <n>
(define (i386:XXjump n)
(or n urg:XXjump)
`(#xe9 ,@(int->bv32 n))) ; jmp . + <n>
(define (i386:Xjump-nz n)
(or n urg:Xjump-nz)
`(#x0f #x85 ,@(int->bv32 n))) ; jnz . + <n>
(define (i386:Xjump-z n)
(or n urg:Xjump-z)
`(#x0f #x84 ,@(int->bv32 n))) ; jz . + <n>
(define (i386:jump n) ;;FIXME: NEED THIS WEIRDNESS for t.c
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP n=~a\n" n)
barf)
`(#xeb ,(if (>= n 0) (- n 2) (- n 2)))) ; jmp <n>
(define (i386:jump-c n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP n=~a\n" n)
barf)
`(#x72 ,(if (>= n 0) n (- n 2)))) ; jc <n>
(define (i386:Xjump-c n)
(or n urg:Xjump-c)
`(#x0f #x82 ,@(int->bv32 n))) ; jc <n>
(define (i386:jump-cz n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP n=~a\n" n)
barf)
`(#x76 ,(if (>= n 0) n (- n 2)))) ; jna <n>
(define (i386:jump-ncz n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP-ncz n=~a\n" n)
barf)
`(#x77 ,(if (>= n 0) n (- n 2)))) ; ja <n>
(define (i386:jump-nc n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP-nc n=~a\n" n)
barf)
`(#x73 ,(if (>= n 0) n (- n 2)))) ; jnc <n>
(define (i386:Xjump-nc n)
(or n urg:Xjump-nc)
`(#x0f #x83 ,@(int->bv32 n))) ; jnc <n>
(define (i386:jump-z n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP-z n=~a\n" n)
barf)
`(#x74 ,(if (>= n 0) n (- n 2)))) ; jz <n>
(define (i386:jump-nz n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP-nz n=~a\n" n)
barf)
`(#x75 ,(if (>= n 0) n (- n 2)))) ; jnz <n>
(define (i386:test-jump-z n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP-z n=~a\n" n)
barf)
`(#x85 #xc0 ; test %eax,%eax
#x74 ,(if (>= n 0) n (- n 4)))) ; jz <n>
(define (i386:jump-byte-nz n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP-byte-nz n=~a\n" n)
barf)
`(#x84 #xc0 ; test %al,%al
#x75 ,(if (>= n 0) n (- n 4)))) ; jne <n>
(define (i386:jump-byte-z n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP-byte-z n=~a\n" n)
barf)
`(#x84 #xc0 ; test %al,%al
#x74 ,(if (>= n 0) n (- n 4)))) ; jne <n>
(define (i386:byte-test-base)
`(#x38 #xc2)) ; cmp %al,%dl
(define (i386:test-base)
`(#x39 #xd0)) ; cmp %edx,%eax
(define (i386:byte-sub-base)
`(#x28 #xd0)) ; sub %dl,%al
(define (i386:byte-base-sub)
`(#x28 #xd0)) ; sub %al,%dl
(define (i386:sub-base)
`(#x29 #xd0)) ; sub %edx,%eax
(define (i386:base-sub)
`(#x29 #xc2)) ; sub %eax,%edx

135
module/mes/as-i386.scm Normal file
View file

@ -0,0 +1,135 @@
;;; -*-scheme-*-
;;; Mes --- Maxwell Equations of Software
;;; Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of Mes.
;;;
;;; Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with Mes. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; as-i386.scm defines i386 assembly
;;; Code:
(define-module (mes as-i386)
#:use-module (mes elf)
#:export (
i386:accu-not
i386:accu-cmp-value
i386:accu->base
i386:accu->base-address
i386:accu->base-address+n
i386:accu->global
i386:accu->global-address
i386:accu->local
i386:accu-non-zero?
i386:accu-test
i386:accu-zero?
i386:accu+accu
i386:accu+base
i386:accu+value
i386:accu/base
i386:accu%base
i386:accu-base
i386:accu-shl
i386:base-sub
i386:base->accu
i386:base->accu-address
i386:byte-accu->base-address
i386:base->global
i386:base->local
i386:base-mem->accu
i386:byte-base-sub
i386:byte-base->accu-address
i386:byte-base->accu-address+n
i386:byte-base-mem->accu
i386:local-address->accu
i386:byte-local->accu
i386:byte-mem->accu
i386:base-mem+n->accu
i386:byte-mem->base
i386:byte-test-base
i386:byte-sub-base
i386:call
i386:call-accu
i386:formal
i386:function-locals
i386:function-preamble
i386:global-add
i386:global->accu
i386:global->base
i386:global-address->accu
i386:global-address->base
i386:jump
i386:jump
i386:jump-byte-nz
i386:jump-byte-z
i386:jump-c
i386:jump-cz
i386:jump-le
i386:jump-nc
i386:jump-ncz
i386:jump-nz
i386:jump-z
i386:local->accu
i386:local->base
i386:local-add
i386:local-address->accu
i386:local-ptr->accu
i386:local-ptr->base
i386:local-address->base
i386:local-test
i386:mem->accu
i386:mem+n->accu
i386:pop-accu
i386:push-accu
i386:pop-base
i386:push-base
i386:push-global
i386:push-global-address
i386:push-local
i386:push-local-de-ref
i386:push-local-address
i386:ret
i386:ret-local
i386:sub-base
i386:test-base
i386:test-jump-z
i386:value->accu
i386:value->accu-address
i386:value->accu-address+n
i386:value->global
i386:value->local
i386:value->base
i386:xor-accu
i386:xor-zf
;; long jump
i386:Xjump
i386:Xjump
i386:Xjump-c
i386:Xjump-nc
i386:Xjump-nz
i386:Xjump-z
i386:XXjump
i386:accu+n
i386:base+n
i386:base-address->accu-address
))
(include-from-path "mes/as-i386.mes")

View file

@ -24,393 +24,6 @@
;;; Code:
(define (i386:function-preamble)
'(#x55 ; push %ebp
#x89 #xe5)) ; mov %esp,%ebp
;; (define (i386:function-locals)
;; '(#x83 #xec #x20)) ; sub $0x10,%esp -- 8 local vars
(define (i386:function-locals)
'(#x83 #xec #x40)) ; sub $0x10,%esp -- 16 local vars
(define (i386:push-global-address o)
(or o push-global-address)
`(#x68 ,@(int->bv32 o))) ; push $0x<o>
(define (i386:push-global o)
(or o push-global)
`(#xa1 ,@(int->bv32 o) ; mov 0x804a000,%eax
#x50)) ; push %eax
(define (i386:push-local n)
(or n push-local)
`(#xff #x75 ,(- 0 (* 4 n)))) ; pushl 0x<n>(%ebp)
(define (i386:push-local-address n)
(or n push-local-address)
`(#x8d #x45 ,(- 0 (* 4 n)) ; lea 0x<n>(%ebp),%eax
#x50)) ; push %eax
(define (i386:push-local-de-ref n)
(or n push-local-de-ref)
`(#x8b #x45 ,(- 0 (* 4 n)) ; mov -0x<n>(%ebp),%eax
#x0f #xb6 #x00 ; movzbl (%eax),%eax
;;#x0f #xbe #xc0 ; movsbl %al,%eax ***FIXME BYTE****
#x50)) ; push %eax
(define (i386:pop-accu)
'(#x58)) ; pop %eax
(define (i386:push-accu)
'(#x50)) ; push %eax
(define (i386:pop-base)
'(#x5a)) ; pop %eax
(define (i386:push-base)
'(#x52)) ; push %eax
(define (i386:ret)
'(#xc9 ; leave
#xc3)) ; ret
(define (i386:accu->base)
'(#x89 #xc2)) ; mov %eax,%edx
(define (i386:accu->base-address)
'(#x89 #x02)) ; mov %eax,%(edx)
(define (i386:byte-accu->base-address)
'(#x88 #x02)) ; mov %al,%(edx)
(define (i386:accu->base-address+n n)
(or n accu->base-address+n)
`(#x89 #x42 ,n)) ; mov %eax,$0x<n>%(edx)
(define (i386:accu->local n)
(or n accu->local)
`(#x89 #x45 ,(- 0 (* 4 n)))) ; mov %eax,-<0xn>(%ebp)
(define (i386:base->local n)
(or n base->local)
`(#x89 #x55 ,(- 0 (* 4 n)))) ; mov %edx,-<0xn>(%ebp)
(define (i386:base->global n)
(or n base->global)
`(#x89 #x15 ,@(int->bv32 n))) ; mov %edx,0x0
(define (i386:accu->global n)
(or n accu->global)
`(#xa3 ,@(int->bv32 n))) ; mov %eax,0x0
(define (i386:accu->global-address n)
(or n accu->global-address)
`(#x8b #x15 ,@(int->bv32 n) ; mov 0x<n>,%edx
#x89 #x02 )) ; mov %eax,(%edx)
(define (i386:accu-zero?)
'(#x85 #xc0)) ; cmpl %eax,%eax
(define (i386:accu-non-zero?)
(append '(#x85 #xc0) ; cmpl %eax,%eax
(i386:xor-zf)))
(define (i386:accu-shl n)
(or n accu:shl n)
`(#xc1 #xe0 ,n)) ; shl $0x8,%eax
(define (i386:accu+accu)
'(#x01 #xc0)) ; add %eax,%eax
(define (i386:accu+base)
`(#x01 #xd0)) ; add %edx,%eax
(define (i386:accu+value v)
(or v accu+value)
`(#x05 ,@(int->bv32 v))) ; add %eax,%eax
(define (i386:accu-base)
`(#x29 #xd0)) ; sub %edx,%eax
(define (i386:accu/base)
'(#x86 #xd3 ; mov %edx,%ebx
#x31 #xd2 ; xor %edx,%edx
#xf7 #xf3)) ; div %ebx
(define (i386:accu%base)
'(#x86 #xd3 ; mov %edx,%ebx
#x31 #xd2 ; xor %edx,%edx
#xf7 #xf3 ; div %ebx
#x89 #xd0)) ; mov %edx,%eax
(define (i386:base->accu)
'(#x89 #xd0)) ; mov %edx,%eax
(define (i386:local->accu n)
(or n local->accu)
`(#x8b #x45 ,(- 0 (* 4 n)))) ; mov -<0xn>(%ebp),%eax
(define (i386:local-address->accu n)
(or n ladd)
`(#x8d #x45 ,(- 0 (* 4 n)))) ; lea 0x<n>(%ebp),%eax
(define (i386:local-ptr->accu n)
(or n local-ptr->accu)
`(#x89 #xe8 ; mov %ebp,%eax
#x83 #xc0 ,(- 0 (* 4 n)))) ; add $0x<n>,%eax
(define (i386:byte-local->accu n)
(or n byte-local->accu)
`(#x0f #xb6 #x45 ,(- 0 (* 4 n)))) ; movzbl 0x<n>(%ebp),%eax
(define (i386:local->base n)
(or n local->base)
`(#x8b #x55 ,(- 0 (* 4 n)))) ; mov -<0xn>(%ebp),%edx
(define (i386:local-address->base n) ;; DE-REF
(or n local-address->base)
`(#x8d #x55 ,(- 0 (* 4 n)))) ; lea 0x<n>(%ebp),%edx
(define (i386:local-ptr->base n)
(or n local-ptr->base)
`(#x89 #xea ; mov %ebp,%edx
#x83 #xc2 ,(- 0 (* 4 n)))) ; add $0x<n>,%edx
(define (i386:global->base n)
(or n global->base)
`(#xba ,@(int->bv32 n))) ; mov $<n>,%edx
(define (i386:global-address->accu n)
(or n global-address->accu)
`(#xa1 ,@(int->bv32 n))) ; mov 0x<n>,%eax
(define (i386:global-address->base n)
(or n global-address->base)
`(#x8b #x15 ,@(int->bv32 n))) ; mov 0x<n>,%edx
(define (i386:byte-base-mem->accu)
'(#x01 #xd0 ; add %edx,%eax
#x0f #xb6 #x00)) ; movzbl (%eax),%eax
(define (i386:byte-mem->accu)
'(#x0f #xb6 #x00)) ; movzbl (%eax),%eax
(define (i386:byte-mem->base)
'(#x0f #xb6 #x10)) ; movzbl (%eax),%edx
(define (i386:base-mem->accu)
'(#x01 #xd0 ; add %edx,%eax
#x8b #x00)) ; mov (%eax),%eax
(define (i386:mem->accu)
'(#x8b #x00)) ; mov (%eax),%eax
(define (i386:mem+n->accu n)
`(#x8b #x40 ,n)) ; mov 0x<n>(%eax),%eax
(define (i386:base-mem+n->accu n)
(or n base-mem+n->accu)
`(#x01 #xd0 ; add %edx,%eax
#x8b #x40 ,n)) ; mov <n>(%eax),%eax
(define (i386:value->accu v)
(or v urg:value->accu)
`(#xb8 ,@(int->bv32 v))) ; mov $<v>,%eax
(define (i386:value->accu-address v)
`(#xc7 #x00 ,@(int->bv32 v))) ; movl $0x<v>,(%eax)
(define (i386:value->accu-address+n n v)
(or v urg:value->accu-address+n)
`(#xc7 #x40 ,n ,@(int->bv32 v))) ; movl $<v>,0x<n>(%eax)
(define (i386:base->accu-address)
'(#x89 #x10)) ; mov %edx,(%eax)
(define (i386:base-address->accu-address)
'(#x8b #x0a ; mov (%edx),%ecx
#x89 #x08)) ; mov %ecx,(%eax)
(define (i386:accu+n n)
`(#x83 #xc0 ,n)) ; add $0x00,%eax
(define (i386:base+n n)
`(#x83 #xc2 ,n)) ; add $0x00,%edx
(define (i386:byte-base->accu-address)
'(#x88 #x10)) ; mov %dl,(%eax)
(define (i386:byte-base->accu-address+n n)
(or n byte-base->accu-address+n)
`(#x88 #x50 ,n)) ; mov %dl,0x<n>(%eax)
(define (i386:value->base v)
(or v urg:value->base)
`(#xba ,@(int->bv32 v))) ; mov $<v>,%edx
(define (i386:local-add n v)
(or n urg:local-add)
`(#x83 #x45 ,(- 0 (* 4 n)) ,v)) ; addl $<v>,0x<n>(%ebp)
(define (i386:global-add n v)
(or n urg:global-add)
`(#x83 #x05 ,@(int->bv32 n) ,v)) ; addl $<v>,0x<n>
(define (i386:global->accu o)
(or o urg:global->accu)
`(#xb8 ,@(int->bv32 o))) ; mov $<>,%eax
(define (i386:value->global n v)
(or n value->global)
`(#xc7 #x05 ,@(int->bv32 n) ; movl $<v>,(<n>)
,@(int->bv32 v)))
(define (i386:value->local n v)
(or n value->local)
`(#xc7 #x45 ,(- 0 (* 4 n)) ; movl $<v>,0x<n>(%ebp)
,@(int->bv32 v)))
(define (i386:local-test n v)
(or n local-test)
`(#x83 #x7d ,(- 0 (* 4 n)) ,v)) ; cmpl $<v>,0x<n>(%ebp)
(define (i386:call f g ta t d address n)
(or address urg:call)
`(#xe8 ,@(int->bv32 (- address 5)) ; call relative $00
#x83 #xc4 ,(* n 4))) ; add $00,%esp
(define (i386:call-accu f g ta t d n)
`(,@(i386:push-accu)
,@(i386:pop-accu)
#xff #xd0 ; call *%eax
#x83 #xc4 ,(* n 4))) ; add $00,%esp
(define (i386:accu-not)
`(#x0f #x94 #xc0 ; sete %al
#x0f #xb6 #xc0)) ; movzbl %al,%eax
(define (i386:xor-accu v)
(or n urg:xor-accu)
`(#x35 ,@(int->bv32 v))) ;xor $0xff,%eax
(define (i386:xor-zf)
'(#x9f ; lahf
#x80 #xf4 #x40 ; xor $0x40,%ah
#x9e)) ; sahf
(define (i386:accu-cmp-value v)
`(#x83 #xf8 ,v)) ; cmp $<v>,%eax
(define (i386:accu-test)
'(#x85 #xc0)) ; test %eax,%eax
(define (i386:Xjump n)
(or n urg:Xjump)
`(#xe9 ,@(int->bv32 (if (>= n 0) n (- n 5))))) ; jmp . + <n>
(define (i386:XXjump n)
(or n urg:XXjump)
`(#xe9 ,@(int->bv32 n))) ; jmp . + <n>
(define (i386:Xjump-nz n)
(or n urg:Xjump-nz)
`(#x0f #x85 ,@(int->bv32 n))) ; jnz . + <n>
(define (i386:Xjump-z n)
(or n urg:Xjump-z)
`(#x0f #x84 ,@(int->bv32 n))) ; jz . + <n>
(define (i386:jump n) ;;FIXME: NEED THIS WEIRDNESS for t.c
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP n=~a\n" n)
barf)
`(#xeb ,(if (>= n 0) (- n 2) (- n 2)))) ; jmp <n>
(define (i386:jump-c n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP n=~a\n" n)
barf)
`(#x72 ,(if (>= n 0) n (- n 2)))) ; jc <n>
(define (i386:Xjump-c n)
(or n urg:Xjump-c)
`(#x0f #x82 ,@(int->bv32 n))) ; jc <n>
(define (i386:jump-cz n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP n=~a\n" n)
barf)
`(#x76 ,(if (>= n 0) n (- n 2)))) ; jna <n>
(define (i386:jump-ncz n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP-ncz n=~a\n" n)
barf)
`(#x77 ,(if (>= n 0) n (- n 2)))) ; ja <n>
(define (i386:jump-nc n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP-nc n=~a\n" n)
barf)
`(#x73 ,(if (>= n 0) n (- n 2)))) ; jnc <n>
(define (i386:Xjump-nc n)
(or n urg:Xjump-nc)
`(#x0f #x83 ,@(int->bv32 n))) ; jnc <n>
(define (i386:jump-z n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP-z n=~a\n" n)
barf)
`(#x74 ,(if (>= n 0) n (- n 2)))) ; jz <n>
(define (i386:jump-nz n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP-nz n=~a\n" n)
barf)
`(#x75 ,(if (>= n 0) n (- n 2)))) ; jnz <n>
(define (i386:test-jump-z n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP-z n=~a\n" n)
barf)
`(#x85 #xc0 ; test %eax,%eax
#x74 ,(if (>= n 0) n (- n 4)))) ; jz <n>
(define (i386:jump-byte-nz n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP-byte-nz n=~a\n" n)
barf)
`(#x84 #xc0 ; test %al,%al
#x75 ,(if (>= n 0) n (- n 4)))) ; jne <n>
(define (i386:jump-byte-z n)
(when (or (> n #x80) (< n #x-80))
(format (current-error-port) "JUMP-byte-z n=~a\n" n)
barf)
`(#x84 #xc0 ; test %al,%al
#x74 ,(if (>= n 0) n (- n 4)))) ; jne <n>
(define (i386:byte-test-base)
`(#x38 #xc2)) ; cmp %al,%dl
(define (i386:test-base)
`(#x39 #xd0)) ; cmp %edx,%eax
(define (i386:byte-sub-base)
`(#x28 #xd0)) ; sub %dl,%al
(define (i386:byte-base-sub)
`(#x28 #xd0)) ; sub %al,%dl
(define (i386:sub-base)
`(#x29 #xd0)) ; sub %edx,%eax
(define (i386:base-sub)
`(#x29 #xc2)) ; sub %eax,%edx
;;; libc bits
(define (i386:exit f g ta t d)
`(
#x5b ; pop %ebx
@ -466,44 +79,20 @@
#xc3 ; ret
))
#!
08048121 <strcmp>:
8048121: 55 push %ebp
8048122: 89 e5 mov %esp,%ebp
8048124: 83 ec 10 sub $0x10,%esp
8048127: eb 08 jmp 8048131 <strcmp+0x10>
(define (i386:_start)
(string-append ".byte"
" 0x89 0xe8" ; mov %ebp,%eax
" 0x83 0xc0 0x08" ; add $0x8,%eax
" 0x50" ; push %eax
" 0x89 0xe8" ; mov %ebp,%eax
" 0x83 0xc0 0x04" ; add $0x4,%eax
" 0x0f 0xb6 0x00" ; movzbl (%eax),%eax
" 0x50" ; push %eax
))
<body>
8048129: 83 45 08 01 addl $0x1,0x8(%ebp)
804812d: 83 45 0c 01 addl $0x1,0xc(%ebp)
<test> *a
8048131: 8b 45 08 mov 0x8(%ebp),%eax
8048134: 0f b6 00 movzbl (%eax),%eax
8048137: 84 c0 test %al,%al
8048139: 74 08 je 8048143 <strcmp+0x22>
<test1> *b
804813b: 8b 45 0c mov 0xc(%ebp),%eax
804813e: 0f b6 00 movzbl (%eax),%eax
8048141: 84 c0 test %al,%al
8048143: 74 10 je 8048155 <strcmp+0x34>
<test2> *a == *b
8048145: 8b 45 08 mov 0x8(%ebp),%eax
8048148: 0f b6 10 movzbl (%eax),%edx
804814b: 8b 45 0c mov 0xc(%ebp),%eax
804814e: 0f b6 00 movzbl (%eax),%eax
8048151: 38 c2 cmp %al,%dl
8048153: 84 c0 test %al,%al
8048155: 75 d2 jne 8048129 <strcmp+0x8>
8048157: 8b 45 08 mov 0x8(%ebp),%eax
804815a: 0f b6 10 movzbl (%eax),%edx
804815d: 8b 45 0c mov 0xc(%ebp),%eax
8048160: 0f b6 00 movzbl (%eax),%eax
8048163: 28 d0 sub %dl,%al
8048165: c9 leave
8048166: c3 ret
!#
(define i386:libc
(list
(cons "exit" (list i386:exit))
(cons "open" (list i386:open))
(cons "read" (list i386:read))
(cons "write" (list i386:write))))

View file

@ -25,124 +25,7 @@
;;; Code:
(define-module (mes libc-i386)
#:use-module (srfi srfi-1)
#:use-module (mes elf)
#:export (
i386:accu-not
i386:accu-cmp-value
i386:accu->base
i386:accu->base-address
i386:accu->base-address+n
i386:accu->global
i386:accu->global-address
i386:accu->local
i386:accu-non-zero?
i386:accu-test
i386:accu-zero?
i386:accu+accu
i386:accu+base
i386:accu+value
i386:accu/base
i386:accu%base
i386:accu-base
i386:accu-shl
i386:base-sub
i386:base->accu
i386:base->accu-address
i386:byte-accu->base-address
i386:base->global
i386:base->local
i386:base-mem->accu
i386:byte-base-sub
i386:byte-base->accu-address
i386:byte-base->accu-address+n
i386:byte-base-mem->accu
i386:local-address->accu
i386:byte-local->accu
i386:byte-mem->accu
i386:base-mem+n->accu
i386:byte-mem->base
i386:byte-test-base
i386:byte-sub-base
i386:call
i386:call-accu
i386:formal
i386:function-locals
i386:function-preamble
i386:global-add
i386:global->accu
i386:global->base
i386:global-address->accu
i386:global-address->base
i386:jump
i386:jump
i386:jump-byte-nz
i386:jump-byte-z
i386:jump-c
i386:jump-cz
i386:jump-le
i386:jump-nc
i386:jump-ncz
i386:jump-nz
i386:jump-z
i386:local->accu
i386:local->base
i386:local-add
i386:local-address->accu
i386:local-ptr->accu
i386:local-ptr->base
i386:local-address->base
i386:local-test
i386:mem->accu
i386:mem+n->accu
i386:pop-accu
i386:push-accu
i386:pop-base
i386:push-base
i386:push-global
i386:push-global-address
i386:push-local
i386:push-local-de-ref
i386:push-local-address
i386:ret
i386:ret-local
i386:sub-base
i386:test-base
i386:test-jump-z
i386:value->accu
i386:value->accu-address
i386:value->accu-address+n
i386:value->global
i386:value->local
i386:value->base
i386:xor-accu
i386:xor-zf
;; long jump
i386:Xjump
i386:Xjump
i386:Xjump-c
i386:Xjump-nc
i386:Xjump-nz
i386:Xjump-z
i386:XXjump
i386:accu+n
i386:base+n
i386:base-address->accu-address
;; libc
i386:exit
i386:open
i386:read
i386:write
))
(cond-expand
(guile-2)
(guile
(use-modules (ice-9 syncase)))
(mes))
#:export (i386:libc
i386:_start))
(include-from-path "mes/libc-i386.mes")

223
module/mes/libc.mes Normal file
View file

@ -0,0 +1,223 @@
;;; -*-scheme-*-
;;; Mes --- Maxwell Equations of Software
;;; Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of Mes.
;;;
;;; Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with Mes. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; libc.mes provides a minimal portable C library for mescc.
;;; Code:
(cond-expand
(guile-2)
(guile)
(mes
(mes-use-module (nyacc lang c99 parser))
(mes-use-module (mes libc-i386))))
(define _start
(let* ((argc-argv (i386:_start))
(ast (with-input-from-string
(string-append "int _start () {int i;asm(\"" argc-argv "\");i=main ();exit (i);}")
parse-c99)))
ast))
(define strlen
(let* ((ast (with-input-from-string
"
int
strlen (char const* s)
{
int i = 0;
while (s[i]) i++;
return i;
}
"
;;paredit:"
parse-c99)))
ast))
(define getchar
(let* ((ast (with-input-from-string
"
int g_stdin;
int
getchar ()
{
char c;
int r = read (g_stdin, &c, 1);
//int r = read (0, &c, 1);
if (r < 1) return -1;
return c;
}
"
;;paredit:"
parse-c99)))
ast))
(define putchar
(let* ((ast (with-input-from-string
"
int
putchar (int c)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
write (1, (char*)&c, 1);
return 0;
}
"
;;paredit:"
parse-c99)))
ast))
(define eputs
(let* ((ast (with-input-from-string
"
int
eputs (char const* s)
{
//write (STDERR, s, strlen (s));
//write (2, s, strlen (s));
int i = strlen (s);
write (2, s, i);
return 0;
}
"
;;paredit:"
parse-c99)))
ast))
(define fputs
(let* ((ast (with-input-from-string
"
int
fputs (char const* s, int fd)
{
int i = strlen (s);
write (fd, s, i);
return 0;
}
"
;;paredit:"
parse-c99)))
ast))
(define puts
(let* ((ast (with-input-from-string
"
int
puts (char const* s)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
int i = strlen (s);
write (1, s, i);
return 0;
}
"
;;paredit:"
parse-c99)))
ast))
(define strcmp
(let* ((ast (with-input-from-string
"
int
strcmp (char const* a, char const* b)
{
while (*a && *b && *a == *b)
{
a++;b++;
}
return *a - *b;
}
"
;;paredit:"
parse-c99)))
ast))
(define itoa
(let* ((ast (with-input-from-string
"
char itoa_buf[10];
char const*
itoa (int x)
{
//static char itoa_buf[10];
//char *p = buf+9;
char *p = itoa_buf;
p += 9;
*p-- = 0;
//int sign = x < 0;
int sign;
sign = x < 0;
if (sign)
x = -x;
do
{
*p-- = '0' + (x % 10);
x = x / 10;
} while (x);
if (sign)
*p-- = '-';
return p+1;
}
"
;;paredit:"
parse-c99)))
ast))
;;;;
(define assert_fail
(let* ((ast (with-input-from-string
"
void
assert_fail (char* s)
{
eputs (\"assert fail: \");
eputs (s);
eputs (\"\n\");
//*((int*)0) = 0;
char *fail = s;
fail = 0;
*fail = 0;
}
"
;;paredit:"
parse-c99)))
ast))
(define libc
(list
strlen
getchar
putchar
eputs
fputs
puts
strcmp
itoa
assert_fail))

36
module/mes/libc.scm Normal file
View file

@ -0,0 +1,36 @@
;;; -*-scheme-*-
;;; Mes --- Maxwell Equations of Software
;;; Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
;;;
;;; This file is part of Mes.
;;;
;;; Mes is free software; you can redistribute it and/or modify it
;;; under the terms of the GNU General Public License as published by
;;; the Free Software Foundation; either version 3 of the License, or (at
;;; your option) any later version.
;;;
;;; Mes is distributed in the hope that it will be useful, but
;;; WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;;; GNU General Public License for more details.
;;;
;;; You should have received a copy of the GNU General Public License
;;; along with Mes. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;;; Code:
(define-module (mes libc)
#:use-module (nyacc lang c99 parser)
#:use-module (mes libc-i386)
#:export (libc _start))
(cond-expand
(guile-2)
(guile
(use-modules (ice-9 syncase)))
(mes))
(include-from-path "mes/libc.mes")

43
mstart.c Normal file
View file

@ -0,0 +1,43 @@
/* -*-comment-start: "//";comment-end:""-*-
* Mes --- Maxwell Equations of Software
* Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
*
* This file is part of Mes.
*
* Mes is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or (at
* your option) any later version.
*
* Mes is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
*/
#if __GNUC__
void
_start ()
{
int r;
asm (
"mov %%ebp,%%eax\n\t"
"addl $8,%%eax\n\t"
"push %%eax\n\t"
"mov %%ebp,%%eax\n\t"
"addl $4,%%eax\n\t"
"movzbl (%%eax),%%eax\n\t"
"push %%eax\n\t"
"call main\n\t"
"movl %%eax,%0\n\t"
: "=r" (r)
: //no inputs "" (&main)
);
exit (r);
}
#endif

View file

@ -18,6 +18,11 @@
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
*/
#if __GNUC__
#include "mlibc.c"
#endif
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
#define MES_MINI 1
#define FIXED_PRIMITIVES 0
@ -35,209 +40,6 @@
char arena[2000];
//char buf0[400];
int g_stdin = 0;
#if __GNUC__
typedef long size_t;
void *malloc (size_t i);
int open (char const *s, int mode);
int read (int fd, void* buf, size_t n);
void write (int fd, char const* s, int n);
void
exit (int code)
{
asm (
"movl %0,%%ebx\n\t"
"movl $1,%%eax\n\t"
"int $0x80"
: // no outputs "=" (r)
: "" (code)
);
// not reached
exit (0);
}
char const*
getenv (char const* p)
{
return 0;
}
int
read (int fd, void* buf, size_t n)
{
int r;
//syscall (SYS_write, fd, s, n));
asm (
"movl %1,%%ebx\n\t"
"movl %2,%%ecx\n\t"
"movl %3,%%edx\n\t"
"movl $0x3,%%eax\n\t"
"int $0x80\n\t"
"mov %%eax,%0\n\t"
: "=r" (r)
: "" (fd), "" (buf), "" (n)
: "eax", "ebx", "ecx", "edx"
);
return r;
}
int
open (char const *s, int mode)
{
int r;
//syscall (SYS_open, mode));
asm (
"mov %1,%%ebx\n\t"
"mov %2,%%ecx\n\t"
"mov $0x5,%%eax\n\t"
"int $0x80\n\t"
"mov %%eax,%0\n\t"
: "=r" (r)
: "" (s), "" (mode)
: "eax", "ebx", "ecx"
);
return r;
}
int
getchar ()
{
char c;
int r = read (g_stdin, &c, 1);
if (r < 1) return -1;
return c;
}
void
write (int fd, char const* s, int n)
{
int r;
//syscall (SYS_write, fd, s, n));
asm (
"mov %0,%%ebx\n\t"
"mov %1,%%ecx\n\t"
"mov %2,%%edx\n\t"
"mov $0x4, %%eax\n\t"
"int $0x80\n\t"
: // no outputs "=" (r)
: "" (fd), "" (s), "" (n)
: "eax", "ebx", "ecx", "edx"
);
}
int
putchar (int c)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
write (1, (char*)&c, 1);
return 0;
}
void *
malloc (size_t size)
{
int *n;
int len = size + sizeof (size);
//n = mmap (0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 );
*n = len;
return (void*)(n+1);
}
void
free (void *p)
{
int *n = (int*)p-1;
//munmap ((void*)p, *n);
}
#define EOF -1
#define STDIN 0
#define STDOUT 1
#define STDERR 2
size_t
strlen (char const* s)
{
int i = 0;
while (s[i]) i++;
return i;
}
int
strcmp (char const* a, char const* b)
{
while (*a && *b && *a == *b) {a++;b++;}
return *a - *b;
}
int
puts (char const* s)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
int i = strlen (s);
write (1, s, i);
return 0;
}
int
eputs (char const* s)
{
//write (STDERR, s, strlen (s));
//int i = write (STDERR, s, strlen (s));
int i = strlen (s);
write (2, s, i);
return 0;
}
char const*
itoa (int x)
{
static char buf[10];
char *p = buf+9;
*p-- = 0;
int sign = x < 0;
if (sign)
x = -x;
do
{
*p-- = '0' + (x % 10);
x = x / 10;
} while (x);
if (sign)
*p-- = '-';
return p+1;
}
#endif
void
assert_fail (char* s)
{
eputs ("assert fail:");
#if __GNUC__
eputs (s);
#endif
eputs ("\n");
#if __GNUC__
*((int*)0) = 0;
#endif
}
#if __GNUC__
#define assert(x) ((x) ? (void)0 : assert_fail ("boo:" #x))
#else
//#define assert(x) ((x) ? (void)0 : assert_fail ("boo:" #x))
#define assert(x) ((x) ? (void)0 : assert_fail (0))
#endif
typedef int SCM;
#if __GNUC__
@ -278,32 +80,6 @@ struct function {
struct scm *g_cells = arena;
//scm *g_news = 0;
// struct scm scm_nil = {SPECIAL, "()"};
// struct scm scm_f = {SPECIAL, "#f"};
// struct scm scm_t = {SPECIAL, "#t"};
// struct scm_dot = {SPECIAL, "."};
// struct scm_arrow = {SPECIAL, "=>"};
// struct scm_undefined = {SPECIAL, "*undefined*"};
// struct scm_unspecified = {SPECIAL, "*unspecified*"};
// struct scm_closure = {SPECIAL, "*closure*"};
// struct scm_circular = {SPECIAL, "*circular*"};
// struct scm_begin = {SPECIAL, "*begin*"};
// struct scm_vm_apply = {SPECIAL, "core:apply"};
// struct scm_vm_apply2 = {SPECIAL, "*vm-apply2*"};
// struct scm_vm_eval = {SPECIAL, "core:eval"};
// struct scm_vm_begin = {SPECIAL, "*vm-begin*"};
// //scm scm_vm_begin_read_input_file = {SPECIAL, "*vm-begin-read-input-file*"};
// struct scm_vm_begin2 = {SPECIAL, "*vm-begin2*"};
// struct scm_vm_return = {SPECIAL, "*vm-return*"};
// //#include "mes.symbols.h"
#define cell_nil 1
#define cell_f 2
#define cell_t 3
@ -341,37 +117,25 @@ struct function g_functions[5];
int g_function = 0;
#if __GNUC__
//FIXME
SCM make_cell (SCM type, SCM car, SCM cdr);
#endif
struct function fun_make_cell = {&make_cell,3,"make-cell"};
struct scm scm_make_cell = {TFUNCTION,0,0};
//, "make-cell", 0};
SCM cell_make_cell;
#if __GNUC__
//FIXME
SCM cons (SCM x, SCM y);
#endif
struct function fun_cons = {&cons,2,"cons"};
struct scm scm_cons = {TFUNCTION,0,0};
// "cons", 0};
SCM cell_cons;
#if __GNUC__
//FIXME
SCM car (SCM x);
#endif
struct function fun_car = {&car,1,"car"};
struct scm scm_car = {TFUNCTION,0,0};
// "car", 0};
SCM cell_car;
#if __GNUC__
//FIXME
SCM cdr (SCM x);
#endif
struct function fun_cdr = {&cdr,1,"cdr"};
struct scm scm_cdr = {TFUNCTION,0,0};
// "cdr", 0};
@ -469,11 +233,11 @@ tmp_num2_ (int x)
SCM
cons (SCM x, SCM y)
{
#if 0
puts ("cons x=");
#if __GNUC__
puts (itoa (x));
#endif
puts ("\n");
#endif
VALUE (tmp_num) = PAIR;
return make_cell (tmp_num, x, y);
}
@ -481,11 +245,11 @@ cons (SCM x, SCM y)
SCM
car (SCM x)
{
#if 0
puts ("car x=");
#if __GNUC__
puts (itoa (x));
#endif
puts ("\n");
#endif
#if MES_MINI
//Nyacc
//assert ("!car");
@ -498,11 +262,11 @@ car (SCM x)
SCM
cdr (SCM x)
{
#if 0
puts ("cdr x=");
#if __GNUC__
puts (itoa (x));
#endif
puts ("\n");
#endif
#if MES_MINI
//Nyacc
//assert ("!cdr");
@ -1290,25 +1054,5 @@ main (int argc, char *argv[])
}
#if __GNUC__
void
_start ()
{
int r;
asm (
"mov %%ebp,%%eax\n\t"
"addl $8,%%eax\n\t"
"push %%eax\n\t"
"mov %%ebp,%%eax\n\t"
"addl $4,%%eax\n\t"
"movzbl (%%eax),%%eax\n\t"
"push %%eax\n\t"
"call main\n\t"
"movl %%eax,%0\n\t"
: "=r" (r)
: //no inputs "" (&main)
);
exit (r);
}
#include "mstart.c"
#endif

View file

@ -18,115 +18,10 @@
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
*/
int g_stdin = 0;
typedef long size_t;
#if __GNUC__
void
exit (int code)
{
asm (
"movl %0,%%ebx\n\t"
"movl $1,%%eax\n\t"
"int $0x80"
: // no outputs "=" (r)
: "" (code)
);
// not reached
exit (0);
}
int
read (int fd, void* buf, size_t n)
{
int r;
//syscall (SYS_write, fd, s, n));
asm (
"movl %1,%%ebx\n\t"
"movl %2,%%ecx\n\t"
"movl %3,%%edx\n\t"
"movl $0x3,%%eax\n\t"
"int $0x80\n\t"
"mov %%eax,%0\n\t"
: "=r" (r)
: "" (fd), "" (buf), "" (n)
: "eax", "ebx", "ecx", "edx"
);
return r;
}
int
open (char const *s, int mode)
{
int r;
//syscall (SYS_open, mode));
asm (
"mov %1,%%ebx\n\t"
"mov %2,%%ecx\n\t"
"mov $0x5,%%eax\n\t"
"int $0x80\n\t"
"mov %%eax,%0\n\t"
: "=r" (r)
: "" (s), "" (mode)
: "eax", "ebx", "ecx"
);
return r;
}
int
getchar ()
{
char c;
int r = read (g_stdin, &c, 1);
if (r < 1) return -1;
return c;
}
void
write (int fd, char const* s, int n)
{
int r;
//syscall (SYS_write, fd, s, n));
asm (
"mov %0,%%ebx\n\t"
"mov %1,%%ecx\n\t"
"mov %2,%%edx\n\t"
"mov $0x4, %%eax\n\t"
"int $0x80\n\t"
: // no outputs "=" (r)
: "" (fd), "" (s), "" (n)
: "eax", "ebx", "ecx", "edx"
);
}
int
putchar (int c)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
write (1, (char*)&c, 1);
return 0;
}
size_t
strlen (char const* s)
{
int i = 0;
while (s[i]) i++;
return i;
}
int
puts (char const* s)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
int i = strlen (s);
write (1, s, i);
return 0;
}
#include "mlibc.c"
#endif
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
int
main (int argc, char *argv[])
@ -141,25 +36,5 @@ main (int argc, char *argv[])
}
#if __GNUC__
void
_start ()
{
int r;
asm (
"mov %%ebp,%%eax\n\t"
"addl $8,%%eax\n\t"
"push %%eax\n\t"
"mov %%ebp,%%eax\n\t"
"addl $4,%%eax\n\t"
"movzbl (%%eax),%%eax\n\t"
"push %%eax\n\t"
"call main\n\t"
"movl %%eax,%0\n\t"
: "=r" (r)
: //no inputs "" (&main)
);
exit (r);
}
#include "mstart.c"
#endif

View file

@ -18,6 +18,12 @@
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
*/
#if __GNUC__
#include "mlibc.c"
#endif
#define assert(x) ((x) ? (void)0 : assert_fail(#x))
#define MES_MINI 1
#if __GNUC__
@ -30,168 +36,6 @@
#define NYACC2 nyacc2
#endif
#if __GNUC__
typedef long size_t;
void *malloc (size_t i);
int open (char const *s, int mode);
int read (int fd, int n);
void write (int fd, char const* s, int n);
void
exit (int code)
{
asm (
"movl %0,%%ebx\n\t"
"movl $1,%%eax\n\t"
"int $0x80"
: // no outputs "=" (r)
: "" (code)
);
// not reached
exit (0);
}
char const*
getenv (char const* p)
{
return 0;
}
int
open (char const *s, int mode)
{
//return syscall (SYS_open, s, mode);
return 0;
}
int
read (int fd, int n)
{
//syscall (SYS_read, 1, 1);
return 0;
}
void
write (int fd, char const* s, int n)
{
int r;
//syscall (SYS_write, fd, s, n));
asm (
"mov %0,%%ebx\n\t"
"mov %1,%%ecx\n\t"
"mov %2,%%edx\n\t"
"mov $0x4, %%eax\n\t"
"int $0x80\n\t"
: // no outputs "=" (r)
: "" (fd), "" (s), "" (n)
: "eax", "ebx", "ecx", "edx"
);
}
void *
malloc (size_t size)
{
int *n;
int len = size + sizeof (size);
//n = mmap (0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 );
*n = len;
return (void*)(n+1);
}
void
free (void *p)
{
int *n = (int*)p-1;
//munmap ((void*)p, *n);
}
#define EOF -1
#define STDIN 0
#define STDOUT 1
#define STDERR 2
//#include <stdio.h>
//#include <string.h>
//#include <stdlib.h>
int g_stdin;
size_t
strlen (char const* s)
{
int i = 0;
while (s[i]) i++;
return i;
}
int
strcmp (char const* a, char const* b)
{
while (*a && *b && *a == *b) {a++;b++;}
return *a - *b;
}
int
getchar ()
{
return read (g_stdin, 1);
}
int
puts (char const* s)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
int i = strlen (s);
write (1, s, i);
return 0;
}
int
eputs (char const* s)
{
//write (STDERR, s, strlen (s));
//int i = write (STDERR, s, strlen (s));
int i = strlen (s);
write (2, s, i);
return 0;
}
char const*
itoa (int x)
{
static char buf[10];
char *p = buf+9;
*p-- = 0;
int sign = x < 0;
if (sign)
x = -x;
do
{
*p-- = '0' + (x % 10);
x = x / 10;
} while (x);
if (sign)
*p-- = '-';
return p+1;
}
void
assert_fail (char* s)
{
eputs ("assert fail:");
eputs (s);
eputs ("\n");
*((int*)0) = 0;
}
#endif
#define assert(x) ((x) ? (void)0 : assert_fail(#x))
typedef int SCM;
#if __GNUC__
@ -267,25 +111,5 @@ main (int argc, char *argv[])
}
#if __GNUC__
void
_start ()
{
int r;
asm (
"mov %%ebp,%%eax\n\t"
"addl $8,%%eax\n\t"
"push %%eax\n\t"
"mov %%ebp,%%eax\n\t"
"addl $4,%%eax\n\t"
"movzbl (%%eax),%%eax\n\t"
"push %%eax\n\t"
"call main\n\t"
"movl %%eax,%0\n\t"
: "=r" (r)
: //no inputs "" (&main)
);
exit (r);
}
#include "mstart.c"
#endif

View file

@ -18,6 +18,11 @@
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
*/
#if __GNUC__
#include "mlibc.c"
#endif
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
#define MES_MINI 1
#define FIXED_PRIMITIVES 0
@ -35,220 +40,6 @@
int ARENA_SIZE = 1200000;
char arena[1200000];
int g_stdin = 0;
#if __GNUC__
typedef long size_t;
void *malloc (size_t i);
int open (char const *s, int mode);
int read (int fd, void* buf, size_t n);
void write (int fd, char const* s, int n);
void
exit (int code)
{
asm (
"movl %0,%%ebx\n\t"
"movl $1,%%eax\n\t"
"int $0x80"
: // no outputs "=" (r)
: "" (code)
);
// not reached
exit (0);
}
char const*
getenv (char const* p)
{
return 0;
}
int
read (int fd, void* buf, size_t n)
{
int r;
//syscall (SYS_write, fd, s, n));
asm (
"movl %1,%%ebx\n\t"
"movl %2,%%ecx\n\t"
"movl %3,%%edx\n\t"
"movl $0x3,%%eax\n\t"
"int $0x80\n\t"
"mov %%eax,%0\n\t"
: "=r" (r)
: "" (fd), "" (buf), "" (n)
: "eax", "ebx", "ecx", "edx"
);
return r;
}
int
open (char const *s, int mode)
{
int r;
//syscall (SYS_open, mode));
asm (
"mov %1,%%ebx\n\t"
"mov %2,%%ecx\n\t"
"mov $0x5,%%eax\n\t"
"int $0x80\n\t"
"mov %%eax,%0\n\t"
: "=r" (r)
: "" (s), "" (mode)
: "eax", "ebx", "ecx"
);
return r;
}
int puts (char const*);
char const* itoa (int);
int
getchar ()
{
char c;
int r = read (g_stdin, &c, 1);
if (r < 1) return -1;
int i = c;
if (i < 0) i += 256;
return i;
}
void
write (int fd, char const* s, int n)
{
int r;
//syscall (SYS_write, fd, s, n));
asm (
"mov %0,%%ebx\n\t"
"mov %1,%%ecx\n\t"
"mov %2,%%edx\n\t"
"mov $0x4, %%eax\n\t"
"int $0x80\n\t"
: // no outputs "=" (r)
: "" (fd), "" (s), "" (n)
: "eax", "ebx", "ecx", "edx"
);
}
int
putchar (int c)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
write (1, (char*)&c, 1);
return 0;
}
void *
malloc (size_t size)
{
int *n;
int len = size + sizeof (size);
//n = mmap (0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 );
*n = len;
return (void*)(n+1);
}
void
free (void *p)
{
int *n = (int*)p-1;
//munmap ((void*)p, *n);
}
#define EOF -1
#define STDIN 0
#define STDOUT 1
#define STDERR 2
size_t
strlen (char const* s)
{
int i = 0;
while (s[i]) i++;
return i;
}
int
strcmp (char const* a, char const* b)
{
while (*a && *b && *a == *b) {a++;b++;}
return *a - *b;
}
int
puts (char const* s)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
int i = strlen (s);
write (1, s, i);
return 0;
}
int
eputs (char const* s)
{
//write (STDERR, s, strlen (s));
//int i = write (STDERR, s, strlen (s));
int i = strlen (s);
write (2, s, i);
return 0;
}
#endif
char itoa_buf[10];
char const*
itoa (int x)
{
//static char itoa_buf[10];
//char *p = buf+9;
char *p = itoa_buf;
p += 9;
*p-- = 0;
//int sign = x < 0;
int sign;
sign = x < 0;
if (sign)
x = -x;
do
{
*p-- = '0' + (x % 10);
x = x / 10;
} while (x);
if (sign)
*p-- = '-';
return p+1;
}
void
assert_fail (char* s)
{
eputs ("assert fail:");
#if __GNUC__
eputs (s);
#endif
eputs ("\n");
#if __GNUC__
*((int*)0) = 0;
#endif
}
#if __GNUC__
#define assert(x) ((x) ? (void)0 : assert_fail ("boo:" #x))
#else
//#define assert(x) ((x) ? (void)0 : assert_fail ("boo:" #x))
#define assert(x) ((x) ? (void)0 : assert_fail (0))
#endif
typedef int SCM;
int g_debug = 0;
@ -415,7 +206,9 @@ int g_function = 0;
SCM
alloc (int n)
{
#if __GNUC__
assert (g_free + n < ARENA_SIZE);
#endif
SCM x = g_free;
g_free += n;
return x;
@ -427,7 +220,9 @@ SCM
make_cell (SCM type, SCM car, SCM cdr)
{
SCM x = alloc (1);
#if __GNUC__
assert (TYPE (type) == TNUMBER);
#endif
TYPE (x) = VALUE (type);
if (VALUE (type) == TCHAR || VALUE (type) == TNUMBER) {
if (car) CAR (x) = CAR (car);
@ -557,7 +352,9 @@ SCM
append2 (SCM x, SCM y)
{
if (x == cell_nil) return y;
#if __GNUC__
assert (TYPE (x) == TPAIR);
#endif
return cons (car (x), append2 (cdr (x), y));
}
@ -616,7 +413,9 @@ assq_ref_env (SCM x, SCM a)
SCM
set_car_x (SCM x, SCM e)
{
#if __GNUC__
assert (TYPE (x) == TPAIR);
#endif
CAR (x) = e;
return cell_unspecified;
}
@ -1068,8 +867,10 @@ SCM
list_of_char_equal_p (SCM a, SCM b)
{
while (a != cell_nil && b != cell_nil && VALUE (car (a)) == VALUE (car (b))) {
#if __GNUC__
assert (TYPE (car (a)) == TCHAR);
assert (TYPE (car (b)) == TCHAR);
#endif
a = cdr (a);
b = cdr (b);
}
@ -1132,7 +933,9 @@ write_byte (SCM x) ///((arity . n))
int fd = 1;
if (TYPE (p) == TPAIR && TYPE (car (p)) == TNUMBER) fd = VALUE (car (p));
//FILE *f = fd == 1 ? stdout : stderr;
#if __GNUC__
assert (TYPE (c) == TNUMBER || TYPE (c) == TCHAR);
#endif
// fputc (VALUE (c), f);
char cc = VALUE (c);
write (1, (char*)&cc, fd);
@ -1454,25 +1257,5 @@ main (int argc, char *argv[])
}
#if __GNUC__
void
_start ()
{
int r;
asm (
"mov %%ebp,%%eax\n\t"
"addl $8,%%eax\n\t"
"push %%eax\n\t"
"mov %%ebp,%%eax\n\t"
"addl $4,%%eax\n\t"
"movzbl (%%eax),%%eax\n\t"
"push %%eax\n\t"
"call main\n\t"
"movl %%eax,%0\n\t"
: "=r" (r)
: //no inputs "" (&main)
);
exit (r);
}
#include "mstart.c"
#endif

View file

@ -19,75 +19,9 @@
*/
#if __GNUC__
void
exit (int code)
{
asm (
"movl %0,%%ebx\n\t"
"movl $1,%%eax\n\t"
"int $0x80"
: // no outputs "=" (r)
: "" (code)
);
// not reached
exit (0);
}
void
write (int fd, char const* s, int n)
{
int r;
//syscall (SYS_write, fd, s, n));
asm (
"mov %0,%%ebx\n\t"
"mov %1,%%ecx\n\t"
"mov %2,%%edx\n\t"
"mov $0x4,%%eax\n\t"
"int $0x80\n\t"
: // no outputs "=" (r)
: "" (fd), "" (s), "" (n)
: "eax", "ebx", "ecx", "edx"
);
}
#define STDOUT 1
typedef long size_t;
size_t
strlen (char const* s)
{
int i = 0;
while (s[i]) i++;
return i;
}
int
puts (char const* s)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
int i = strlen (s);
write (1, s, i);
return 0;
}
int
putchar (int c)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
write (1, (char*)&c, 1);
return 0;
}
int
strcmp (char const* a, char const* b)
{
while (*a && *b && *a == *b) {a++;b++;}
return *a - *b;
}
#include "mlibc.c"
#endif
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
struct scm {
int type;
@ -136,36 +70,6 @@ struct scm scm_fun = {TFUNCTION,0,0};
SCM cell_fun;
#if 1
char itoa_buf[10];
char const*
itoa (int x)
{
//static char itoa_buf[10];
//char *p = buf+9;
char *p = itoa_buf;
p += 9;
*p-- = 0;
//int sign = x < 0;
int sign;
sign = x < 0;
if (sign)
x = -x;
do
{
*p-- = '0' + (x % 10);
x = x / 10;
} while (x);
if (sign)
*p-- = '-';
return p+1;
}
int
add (int a, int b)
{
@ -546,6 +450,12 @@ test (char *p)
puts ("t: (f) ?\n");
(f) ? exit (1) : 1;
puts ("t: assert (1) ?\n");
assert (1);
puts ("t: assert (f==0) ?\n");
assert (f==0);
puts ("t: p[0] != 't'\n");
if (p[0] != 't') return p[0];
@ -758,28 +668,5 @@ main (int argc, char *argv[])
}
#if __GNUC__
void
_start ()
{
// int r=main ();
// exit (r);
int r;
asm (
"mov %%ebp,%%eax\n\t"
"addl $8,%%eax\n\t"
"push %%eax\n\t"
"mov %%ebp,%%eax\n\t"
"addl $4,%%eax\n\t"
"movzbl (%%eax),%%eax\n\t"
"push %%eax\n\t"
"call main\n\t"
"movl %%eax,%0\n\t"
: "=r" (r)
: //no inputs "" (&main)
);
exit (r);
}
#include "mstart.c"
#endif

View file

@ -18,6 +18,11 @@
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
*/
#if __GNUC__
#include "mlibc.c"
#endif
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
#define MES_MINI 1
#if __GNUC__
@ -33,210 +38,6 @@
char arena[200];
int g_stdin = 0;
#if __GNUC__
typedef long size_t;
void *malloc (size_t i);
int open (char const *s, int mode);
int read (int fd, void* buf, size_t n);
void write (int fd, char const* s, int n);
void
exit (int code)
{
asm (
"movl %0,%%ebx\n\t"
"movl $1,%%eax\n\t"
"int $0x80"
: // no outputs "=" (r)
: "" (code)
);
// not reached
exit (0);
}
char const*
getenv (char const* p)
{
return 0;
}
int
read (int fd, void* buf, size_t n)
{
int r;
//syscall (SYS_write, fd, s, n));
asm (
"movl %1,%%ebx\n\t"
"movl %2,%%ecx\n\t"
"movl %3,%%edx\n\t"
"movl $0x3,%%eax\n\t"
"int $0x80\n\t"
"mov %%eax,%0\n\t"
: "=r" (r)
: "" (fd), "" (buf), "" (n)
: "eax", "ebx", "ecx", "edx"
);
return r;
}
int
open (char const *s, int mode)
{
int r;
//syscall (SYS_open, mode));
asm (
"mov %1,%%ebx\n\t"
"mov %2,%%ecx\n\t"
"mov $0x5,%%eax\n\t"
"int $0x80\n\t"
"mov %%eax,%0\n\t"
: "=r" (r)
: "" (s), "" (mode)
: "eax", "ebx", "ecx"
);
return r;
}
int
getchar ()
{
char c;
int r = read (g_stdin, &c, 1);
if (r < 1) return -1;
return c;
}
void
write (int fd, char const* s, int n)
{
int r;
//syscall (SYS_write, fd, s, n));
asm (
"mov %0,%%ebx\n\t"
"mov %1,%%ecx\n\t"
"mov %2,%%edx\n\t"
"mov $0x4, %%eax\n\t"
"int $0x80\n\t"
: // no outputs "=" (r)
: "" (fd), "" (s), "" (n)
: "eax", "ebx", "ecx", "edx"
);
}
int
putchar (int c)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
write (1, (char*)&c, 1);
return 0;
}
void *
malloc (size_t size)
{
int *n;
int len = size + sizeof (size);
//n = mmap (0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 );
*n = len;
return (void*)(n+1);
}
void
free (void *p)
{
int *n = (int*)p-1;
//munmap ((void*)p, *n);
}
#define EOF -1
#define STDIN 0
#define STDOUT 1
#define STDERR 2
size_t
strlen (char const* s)
{
int i = 0;
while (s[i]) i++;
return i;
}
int
strcmp (char const* a, char const* b)
{
while (*a && *b && *a == *b) {a++;b++;}
return *a - *b;
}
int
puts (char const* s)
{
//write (STDOUT, s, strlen (s));
//int i = write (STDOUT, s, strlen (s));
int i = strlen (s);
write (1, s, i);
return 0;
}
int
eputs (char const* s)
{
//write (STDERR, s, strlen (s));
//int i = write (STDERR, s, strlen (s));
int i = strlen (s);
write (2, s, i);
return 0;
}
char const*
itoa (int x)
{
static char buf[10];
char *p = buf+9;
*p-- = 0;
int sign = x < 0;
if (sign)
x = -x;
do
{
*p-- = '0' + (x % 10);
x = x / 10;
} while (x);
if (sign)
*p-- = '-';
return p+1;
}
#endif
void
assert_fail (char* s)
{
eputs ("assert fail:");
#if __GNUC__
eputs (s);
#endif
eputs ("\n");
#if __GNUC__
*((int*)0) = 0;
#endif
}
#if __GNUC__
#define assert(x) ((x) ? (void)0 : assert_fail ("boo:" #x))
#else
//#define assert(x) ((x) ? (void)0 : assert_fail ("boo:" #x))
#define assert(x) ((x) ? (void)0 : assert_fail (0))
#endif
typedef int SCM;
#if __GNUC__
@ -567,26 +368,5 @@ main (int argc, char *argv[])
}
#if __GNUC__
void
_start ()
{
int r;
asm (
"mov %%ebp,%%eax\n\t"
"addl $8,%%eax\n\t"
"push %%eax\n\t"
"mov %%ebp,%%eax\n\t"
"addl $4,%%eax\n\t"
"movzbl (%%eax),%%eax\n\t"
"push %%eax\n\t"
"call main\n\t"
"movl %%eax,%0\n\t"
: "=r" (r)
: //no inputs "" (&main)
);
exit (r);
}
#include "mstart.c"
#endif