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:
parent
124352e087
commit
4e12e14b85
14
GNUmakefile
14
GNUmakefile
|
@ -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: GNUmakefile
|
||||||
mini-mes: doc/examples/mini-mes.c
|
mini-mes: doc/examples/mini-mes.c
|
||||||
rm -f $@
|
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 $@
|
chmod +x $@
|
||||||
|
|
||||||
cons-mes: scaffold/cons-mes.c GNUmakefile
|
cons-mes: scaffold/cons-mes.c GNUmakefile
|
||||||
rm -f $@
|
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 $@
|
chmod +x $@
|
||||||
|
|
||||||
tiny-mes: scaffold/tiny-mes.c GNUmakefile
|
tiny-mes: scaffold/tiny-mes.c GNUmakefile
|
||||||
rm -f $@
|
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 $@
|
chmod +x $@
|
||||||
|
|
||||||
m: scaffold/m.c GNUmakefile
|
m: scaffold/m.c GNUmakefile
|
||||||
rm -f $@
|
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"' $<
|
# gcc --std=gnu99 -g -o $@ '-DVERSION="0.4"' $<
|
||||||
chmod +x $@
|
chmod +x $@
|
||||||
|
|
||||||
micro-mes: scaffold/micro-mes.c GNUmakefile
|
micro-mes: scaffold/micro-mes.c GNUmakefile
|
||||||
rm -f $@
|
rm -f $@
|
||||||
gcc -nostdlib --std=gnu99 -m32 -o $@ '-DVERSION="0.4"' $<
|
gcc -nostdlib -I. --std=gnu99 -m32 -o $@ '-DVERSION="0.4"' $<
|
||||||
chmod +x $@
|
chmod +x $@
|
||||||
|
|
||||||
main: doc/examples/main.c GNUmakefile
|
main: doc/examples/main.c GNUmakefile
|
||||||
rm -f $@
|
rm -f $@
|
||||||
gcc -nostdlib --std=gnu99 -m32 -o $@ '-DVERSION="0.4"' $<
|
gcc -nostdlib -I. --std=gnu99 -m32 -o $@ '-DVERSION="0.4"' $<
|
||||||
chmod +x $@
|
chmod +x $@
|
||||||
|
|
||||||
t: scaffold/t.c GNUmakefile
|
t: scaffold/t.c GNUmakefile
|
||||||
rm -f $@
|
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 $@
|
chmod +x $@
|
||||||
|
|
||||||
MAIN_C:=doc/examples/main.c
|
MAIN_C:=doc/examples/main.c
|
||||||
|
|
|
@ -19,65 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
void
|
#include "mlibc.c"
|
||||||
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;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -90,27 +32,5 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
void
|
#include "mstart.c"
|
||||||
_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);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
230
mlibc.c
Normal file
230
mlibc.c
Normal 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
|
|
@ -57,22 +57,6 @@
|
||||||
(define (.name o)
|
(define (.name o)
|
||||||
(cadr 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)
|
(define (.statement o)
|
||||||
(and (pair? o)
|
(and (pair? o)
|
||||||
(eq? (car o) 'function)
|
(eq? (car o) 'function)
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
;;(define barf #f)
|
|
||||||
|
|
||||||
(cond-expand
|
(cond-expand
|
||||||
(guile-2
|
(guile-2
|
||||||
(set-port-encoding! (current-output-port) "ISO-8859-1"))
|
(set-port-encoding! (current-output-port) "ISO-8859-1"))
|
||||||
|
@ -36,7 +34,8 @@
|
||||||
(mes-use-module (mes elf-util))
|
(mes-use-module (mes elf-util))
|
||||||
(mes-use-module (mes pmatch))
|
(mes-use-module (mes pmatch))
|
||||||
(mes-use-module (mes elf))
|
(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))))
|
(mes-use-module (mes optargs))))
|
||||||
|
|
||||||
(define (logf port string . rest)
|
(define (logf port string . rest)
|
||||||
|
@ -363,8 +362,20 @@ _)))))
|
||||||
(abs-declr (pointer)))
|
(abs-declr (pointer)))
|
||||||
,cast)
|
,cast)
|
||||||
((expr->arg info) 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
|
barf
|
||||||
0)))))
|
0)))))
|
||||||
|
|
||||||
|
@ -767,20 +778,33 @@ _)))))
|
||||||
(accu ((expr->accu empty) a))
|
(accu ((expr->accu empty) a))
|
||||||
(base ((expr->base empty) b)))
|
(base ((expr->base empty) b)))
|
||||||
(clone info #:text
|
(clone info #:text
|
||||||
(append text
|
(append text ;;FIXME:empty
|
||||||
(.text accu)
|
(.text accu)
|
||||||
(.text base)
|
(.text base)
|
||||||
(list (lambda (f g ta t d)
|
(list (lambda (f g ta t d)
|
||||||
(i386:accu%base)))))))
|
(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
|
;; FIXME: c/p ast->info
|
||||||
((lt ,a ,b)
|
((lt ,a ,b)
|
||||||
(let* ((base ((expr->base info) a))
|
(let* ((base ((expr->base info) a))
|
||||||
(empty (clone base #:text '()))
|
(empty (clone base #:text '()))
|
||||||
(accu ((expr->accu empty) b)))
|
(accu ((expr->accu empty) b)))
|
||||||
(clone info #:text
|
(clone info #:text
|
||||||
(append text
|
(append (.text base)
|
||||||
(.text base)
|
|
||||||
(.text accu)
|
(.text accu)
|
||||||
(list (lambda (f g ta t d)
|
(list (lambda (f g ta t d)
|
||||||
(i386:base-sub)))))))
|
(i386:base-sub)))))))
|
||||||
|
@ -1187,7 +1211,7 @@ _)))))
|
||||||
(locals (cons (make-local name type pointer id) locals)))
|
(locals (cons (make-local name type pointer id) locals)))
|
||||||
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 " 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 " text=~a\n" text)
|
||||||
;; (stderr " info=~a\n" info)
|
;; (stderr " info=~a\n" info)
|
||||||
|
@ -2325,155 +2349,6 @@ _)))))
|
||||||
(if (null? elements) info
|
(if (null? elements) info
|
||||||
(loop (cdr elements) ((ast->info info) (car elements)))))))
|
(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)
|
(define (compile)
|
||||||
(let* ((ast (mescc))
|
(let* ((ast (mescc))
|
||||||
(info (make <info>
|
(info (make <info>
|
||||||
|
|
|
@ -29,7 +29,9 @@
|
||||||
#:use-module (ice-9 pretty-print)
|
#:use-module (ice-9 pretty-print)
|
||||||
#:use-module (mes elf)
|
#:use-module (mes elf)
|
||||||
#:use-module (mes elf-util)
|
#:use-module (mes elf-util)
|
||||||
|
#:use-module (mes as-i386)
|
||||||
#:use-module (mes libc-i386)
|
#:use-module (mes libc-i386)
|
||||||
|
#:use-module (mes libc)
|
||||||
#:use-module (nyacc lang c99 parser)
|
#:use-module (nyacc lang c99 parser)
|
||||||
#:export (compile))
|
#:export (compile))
|
||||||
|
|
||||||
|
|
418
module/mes/as-i386.mes
Normal file
418
module/mes/as-i386.mes
Normal 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
135
module/mes/as-i386.scm
Normal 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")
|
|
@ -24,393 +24,6 @@
|
||||||
|
|
||||||
;;; Code:
|
;;; 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)
|
(define (i386:exit f g ta t d)
|
||||||
`(
|
`(
|
||||||
#x5b ; pop %ebx
|
#x5b ; pop %ebx
|
||||||
|
@ -466,44 +79,20 @@
|
||||||
#xc3 ; ret
|
#xc3 ; ret
|
||||||
))
|
))
|
||||||
|
|
||||||
#!
|
(define (i386:_start)
|
||||||
08048121 <strcmp>:
|
(string-append ".byte"
|
||||||
8048121: 55 push %ebp
|
" 0x89 0xe8" ; mov %ebp,%eax
|
||||||
8048122: 89 e5 mov %esp,%ebp
|
" 0x83 0xc0 0x08" ; add $0x8,%eax
|
||||||
8048124: 83 ec 10 sub $0x10,%esp
|
" 0x50" ; push %eax
|
||||||
8048127: eb 08 jmp 8048131 <strcmp+0x10>
|
" 0x89 0xe8" ; mov %ebp,%eax
|
||||||
|
" 0x83 0xc0 0x04" ; add $0x4,%eax
|
||||||
|
" 0x0f 0xb6 0x00" ; movzbl (%eax),%eax
|
||||||
|
" 0x50" ; push %eax
|
||||||
|
))
|
||||||
|
|
||||||
<body>
|
(define i386:libc
|
||||||
8048129: 83 45 08 01 addl $0x1,0x8(%ebp)
|
(list
|
||||||
804812d: 83 45 0c 01 addl $0x1,0xc(%ebp)
|
(cons "exit" (list i386:exit))
|
||||||
|
(cons "open" (list i386:open))
|
||||||
<test> *a
|
(cons "read" (list i386:read))
|
||||||
8048131: 8b 45 08 mov 0x8(%ebp),%eax
|
(cons "write" (list i386:write))))
|
||||||
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
|
|
||||||
!#
|
|
||||||
|
|
|
@ -25,124 +25,7 @@
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(define-module (mes libc-i386)
|
(define-module (mes libc-i386)
|
||||||
#:use-module (srfi srfi-1)
|
#:export (i386:libc
|
||||||
#:use-module (mes elf)
|
i386:_start))
|
||||||
#: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))
|
|
||||||
|
|
||||||
(include-from-path "mes/libc-i386.mes")
|
(include-from-path "mes/libc-i386.mes")
|
||||||
|
|
223
module/mes/libc.mes
Normal file
223
module/mes/libc.mes
Normal 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
36
module/mes/libc.scm
Normal 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
43
mstart.c
Normal 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
|
|
@ -18,6 +18,11 @@
|
||||||
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
|
* 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 MES_MINI 1
|
||||||
#define FIXED_PRIMITIVES 0
|
#define FIXED_PRIMITIVES 0
|
||||||
|
|
||||||
|
@ -35,209 +40,6 @@
|
||||||
char arena[2000];
|
char arena[2000];
|
||||||
//char buf0[400];
|
//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;
|
typedef int SCM;
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
|
@ -278,32 +80,6 @@ struct function {
|
||||||
|
|
||||||
struct scm *g_cells = arena;
|
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_nil 1
|
||||||
#define cell_f 2
|
#define cell_f 2
|
||||||
#define cell_t 3
|
#define cell_t 3
|
||||||
|
@ -341,37 +117,25 @@ struct function g_functions[5];
|
||||||
int g_function = 0;
|
int g_function = 0;
|
||||||
|
|
||||||
|
|
||||||
#if __GNUC__
|
|
||||||
//FIXME
|
|
||||||
SCM make_cell (SCM type, SCM car, SCM cdr);
|
SCM make_cell (SCM type, SCM car, SCM cdr);
|
||||||
#endif
|
|
||||||
struct function fun_make_cell = {&make_cell,3,"make-cell"};
|
struct function fun_make_cell = {&make_cell,3,"make-cell"};
|
||||||
struct scm scm_make_cell = {TFUNCTION,0,0};
|
struct scm scm_make_cell = {TFUNCTION,0,0};
|
||||||
//, "make-cell", 0};
|
//, "make-cell", 0};
|
||||||
SCM cell_make_cell;
|
SCM cell_make_cell;
|
||||||
|
|
||||||
#if __GNUC__
|
|
||||||
//FIXME
|
|
||||||
SCM cons (SCM x, SCM y);
|
SCM cons (SCM x, SCM y);
|
||||||
#endif
|
|
||||||
struct function fun_cons = {&cons,2,"cons"};
|
struct function fun_cons = {&cons,2,"cons"};
|
||||||
struct scm scm_cons = {TFUNCTION,0,0};
|
struct scm scm_cons = {TFUNCTION,0,0};
|
||||||
// "cons", 0};
|
// "cons", 0};
|
||||||
SCM cell_cons;
|
SCM cell_cons;
|
||||||
|
|
||||||
#if __GNUC__
|
|
||||||
//FIXME
|
|
||||||
SCM car (SCM x);
|
SCM car (SCM x);
|
||||||
#endif
|
|
||||||
struct function fun_car = {&car,1,"car"};
|
struct function fun_car = {&car,1,"car"};
|
||||||
struct scm scm_car = {TFUNCTION,0,0};
|
struct scm scm_car = {TFUNCTION,0,0};
|
||||||
// "car", 0};
|
// "car", 0};
|
||||||
SCM cell_car;
|
SCM cell_car;
|
||||||
|
|
||||||
#if __GNUC__
|
|
||||||
//FIXME
|
|
||||||
SCM cdr (SCM x);
|
SCM cdr (SCM x);
|
||||||
#endif
|
|
||||||
struct function fun_cdr = {&cdr,1,"cdr"};
|
struct function fun_cdr = {&cdr,1,"cdr"};
|
||||||
struct scm scm_cdr = {TFUNCTION,0,0};
|
struct scm scm_cdr = {TFUNCTION,0,0};
|
||||||
// "cdr", 0};
|
// "cdr", 0};
|
||||||
|
@ -469,11 +233,11 @@ tmp_num2_ (int x)
|
||||||
SCM
|
SCM
|
||||||
cons (SCM x, SCM y)
|
cons (SCM x, SCM y)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
puts ("cons x=");
|
puts ("cons x=");
|
||||||
#if __GNUC__
|
|
||||||
puts (itoa (x));
|
puts (itoa (x));
|
||||||
#endif
|
|
||||||
puts ("\n");
|
puts ("\n");
|
||||||
|
#endif
|
||||||
VALUE (tmp_num) = PAIR;
|
VALUE (tmp_num) = PAIR;
|
||||||
return make_cell (tmp_num, x, y);
|
return make_cell (tmp_num, x, y);
|
||||||
}
|
}
|
||||||
|
@ -481,11 +245,11 @@ cons (SCM x, SCM y)
|
||||||
SCM
|
SCM
|
||||||
car (SCM x)
|
car (SCM x)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
puts ("car x=");
|
puts ("car x=");
|
||||||
#if __GNUC__
|
|
||||||
puts (itoa (x));
|
puts (itoa (x));
|
||||||
#endif
|
|
||||||
puts ("\n");
|
puts ("\n");
|
||||||
|
#endif
|
||||||
#if MES_MINI
|
#if MES_MINI
|
||||||
//Nyacc
|
//Nyacc
|
||||||
//assert ("!car");
|
//assert ("!car");
|
||||||
|
@ -498,11 +262,11 @@ car (SCM x)
|
||||||
SCM
|
SCM
|
||||||
cdr (SCM x)
|
cdr (SCM x)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
puts ("cdr x=");
|
puts ("cdr x=");
|
||||||
#if __GNUC__
|
|
||||||
puts (itoa (x));
|
puts (itoa (x));
|
||||||
#endif
|
|
||||||
puts ("\n");
|
puts ("\n");
|
||||||
|
#endif
|
||||||
#if MES_MINI
|
#if MES_MINI
|
||||||
//Nyacc
|
//Nyacc
|
||||||
//assert ("!cdr");
|
//assert ("!cdr");
|
||||||
|
@ -1290,25 +1054,5 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
void
|
#include "mstart.c"
|
||||||
_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
|
#endif
|
||||||
|
|
131
scaffold/m.c
131
scaffold/m.c
|
@ -18,115 +18,10 @@
|
||||||
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
|
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int g_stdin = 0;
|
|
||||||
typedef long size_t;
|
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
void
|
#include "mlibc.c"
|
||||||
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;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[])
|
main (int argc, char *argv[])
|
||||||
|
@ -141,25 +36,5 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
void
|
#include "mstart.c"
|
||||||
_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
|
#endif
|
||||||
|
|
|
@ -18,6 +18,12 @@
|
||||||
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
|
* 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 MES_MINI 1
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
|
@ -30,168 +36,6 @@
|
||||||
#define NYACC2 nyacc2
|
#define NYACC2 nyacc2
|
||||||
#endif
|
#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;
|
typedef int SCM;
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
|
@ -267,25 +111,5 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
void
|
#include "mstart.c"
|
||||||
_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
|
#endif
|
||||||
|
|
|
@ -18,6 +18,11 @@
|
||||||
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
|
* 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 MES_MINI 1
|
||||||
#define FIXED_PRIMITIVES 0
|
#define FIXED_PRIMITIVES 0
|
||||||
|
|
||||||
|
@ -35,220 +40,6 @@
|
||||||
int ARENA_SIZE = 1200000;
|
int ARENA_SIZE = 1200000;
|
||||||
char arena[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;
|
typedef int SCM;
|
||||||
|
|
||||||
int g_debug = 0;
|
int g_debug = 0;
|
||||||
|
@ -415,7 +206,9 @@ int g_function = 0;
|
||||||
SCM
|
SCM
|
||||||
alloc (int n)
|
alloc (int n)
|
||||||
{
|
{
|
||||||
|
#if __GNUC__
|
||||||
assert (g_free + n < ARENA_SIZE);
|
assert (g_free + n < ARENA_SIZE);
|
||||||
|
#endif
|
||||||
SCM x = g_free;
|
SCM x = g_free;
|
||||||
g_free += n;
|
g_free += n;
|
||||||
return x;
|
return x;
|
||||||
|
@ -427,7 +220,9 @@ SCM
|
||||||
make_cell (SCM type, SCM car, SCM cdr)
|
make_cell (SCM type, SCM car, SCM cdr)
|
||||||
{
|
{
|
||||||
SCM x = alloc (1);
|
SCM x = alloc (1);
|
||||||
|
#if __GNUC__
|
||||||
assert (TYPE (type) == TNUMBER);
|
assert (TYPE (type) == TNUMBER);
|
||||||
|
#endif
|
||||||
TYPE (x) = VALUE (type);
|
TYPE (x) = VALUE (type);
|
||||||
if (VALUE (type) == TCHAR || VALUE (type) == TNUMBER) {
|
if (VALUE (type) == TCHAR || VALUE (type) == TNUMBER) {
|
||||||
if (car) CAR (x) = CAR (car);
|
if (car) CAR (x) = CAR (car);
|
||||||
|
@ -557,7 +352,9 @@ SCM
|
||||||
append2 (SCM x, SCM y)
|
append2 (SCM x, SCM y)
|
||||||
{
|
{
|
||||||
if (x == cell_nil) return y;
|
if (x == cell_nil) return y;
|
||||||
|
#if __GNUC__
|
||||||
assert (TYPE (x) == TPAIR);
|
assert (TYPE (x) == TPAIR);
|
||||||
|
#endif
|
||||||
return cons (car (x), append2 (cdr (x), y));
|
return cons (car (x), append2 (cdr (x), y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,7 +413,9 @@ assq_ref_env (SCM x, SCM a)
|
||||||
SCM
|
SCM
|
||||||
set_car_x (SCM x, SCM e)
|
set_car_x (SCM x, SCM e)
|
||||||
{
|
{
|
||||||
|
#if __GNUC__
|
||||||
assert (TYPE (x) == TPAIR);
|
assert (TYPE (x) == TPAIR);
|
||||||
|
#endif
|
||||||
CAR (x) = e;
|
CAR (x) = e;
|
||||||
return cell_unspecified;
|
return cell_unspecified;
|
||||||
}
|
}
|
||||||
|
@ -1068,8 +867,10 @@ SCM
|
||||||
list_of_char_equal_p (SCM a, SCM b)
|
list_of_char_equal_p (SCM a, SCM b)
|
||||||
{
|
{
|
||||||
while (a != cell_nil && b != cell_nil && VALUE (car (a)) == VALUE (car (b))) {
|
while (a != cell_nil && b != cell_nil && VALUE (car (a)) == VALUE (car (b))) {
|
||||||
|
#if __GNUC__
|
||||||
assert (TYPE (car (a)) == TCHAR);
|
assert (TYPE (car (a)) == TCHAR);
|
||||||
assert (TYPE (car (b)) == TCHAR);
|
assert (TYPE (car (b)) == TCHAR);
|
||||||
|
#endif
|
||||||
a = cdr (a);
|
a = cdr (a);
|
||||||
b = cdr (b);
|
b = cdr (b);
|
||||||
}
|
}
|
||||||
|
@ -1132,7 +933,9 @@ write_byte (SCM x) ///((arity . n))
|
||||||
int fd = 1;
|
int fd = 1;
|
||||||
if (TYPE (p) == TPAIR && TYPE (car (p)) == TNUMBER) fd = VALUE (car (p));
|
if (TYPE (p) == TPAIR && TYPE (car (p)) == TNUMBER) fd = VALUE (car (p));
|
||||||
//FILE *f = fd == 1 ? stdout : stderr;
|
//FILE *f = fd == 1 ? stdout : stderr;
|
||||||
|
#if __GNUC__
|
||||||
assert (TYPE (c) == TNUMBER || TYPE (c) == TCHAR);
|
assert (TYPE (c) == TNUMBER || TYPE (c) == TCHAR);
|
||||||
|
#endif
|
||||||
// fputc (VALUE (c), f);
|
// fputc (VALUE (c), f);
|
||||||
char cc = VALUE (c);
|
char cc = VALUE (c);
|
||||||
write (1, (char*)&cc, fd);
|
write (1, (char*)&cc, fd);
|
||||||
|
@ -1454,25 +1257,5 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
void
|
#include "mstart.c"
|
||||||
_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
|
#endif
|
||||||
|
|
131
scaffold/t.c
131
scaffold/t.c
|
@ -19,75 +19,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
void
|
#include "mlibc.c"
|
||||||
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;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
|
||||||
|
|
||||||
struct scm {
|
struct scm {
|
||||||
int type;
|
int type;
|
||||||
|
@ -136,36 +70,6 @@ struct scm scm_fun = {TFUNCTION,0,0};
|
||||||
SCM cell_fun;
|
SCM cell_fun;
|
||||||
|
|
||||||
#if 1
|
#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
|
int
|
||||||
add (int a, int b)
|
add (int a, int b)
|
||||||
{
|
{
|
||||||
|
@ -546,6 +450,12 @@ test (char *p)
|
||||||
puts ("t: (f) ?\n");
|
puts ("t: (f) ?\n");
|
||||||
(f) ? exit (1) : 1;
|
(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");
|
puts ("t: p[0] != 't'\n");
|
||||||
if (p[0] != 't') return p[0];
|
if (p[0] != 't') return p[0];
|
||||||
|
|
||||||
|
@ -758,28 +668,5 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
void
|
#include "mstart.c"
|
||||||
_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);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -18,6 +18,11 @@
|
||||||
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
|
* 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 MES_MINI 1
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
|
@ -33,210 +38,6 @@
|
||||||
|
|
||||||
char arena[200];
|
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;
|
typedef int SCM;
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
|
@ -567,26 +368,5 @@ main (int argc, char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
#if __GNUC__
|
#if __GNUC__
|
||||||
void
|
#include "mstart.c"
|
||||||
_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
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue