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: doc/examples/mini-mes.c
|
||||
rm -f $@
|
||||
gcc -nostdlib --std=gnu99 -m32 -g -I. -o $@ '-DVERSION="0.4"' $<
|
||||
gcc -nostdlib -I. --std=gnu99 -m32 -g -I. -o $@ '-DVERSION="0.4"' $<
|
||||
chmod +x $@
|
||||
|
||||
cons-mes: scaffold/cons-mes.c GNUmakefile
|
||||
rm -f $@
|
||||
gcc -nostdlib --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
|
||||
gcc -nostdlib -I. --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
|
||||
chmod +x $@
|
||||
|
||||
tiny-mes: scaffold/tiny-mes.c GNUmakefile
|
||||
rm -f $@
|
||||
gcc -nostdlib --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
|
||||
gcc -nostdlib -I. --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
|
||||
chmod +x $@
|
||||
|
||||
m: scaffold/m.c GNUmakefile
|
||||
rm -f $@
|
||||
gcc -nostdlib --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
|
||||
gcc -nostdlib -I. --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
|
||||
# gcc --std=gnu99 -g -o $@ '-DVERSION="0.4"' $<
|
||||
chmod +x $@
|
||||
|
||||
micro-mes: scaffold/micro-mes.c GNUmakefile
|
||||
rm -f $@
|
||||
gcc -nostdlib --std=gnu99 -m32 -o $@ '-DVERSION="0.4"' $<
|
||||
gcc -nostdlib -I. --std=gnu99 -m32 -o $@ '-DVERSION="0.4"' $<
|
||||
chmod +x $@
|
||||
|
||||
main: doc/examples/main.c GNUmakefile
|
||||
rm -f $@
|
||||
gcc -nostdlib --std=gnu99 -m32 -o $@ '-DVERSION="0.4"' $<
|
||||
gcc -nostdlib -I. --std=gnu99 -m32 -o $@ '-DVERSION="0.4"' $<
|
||||
chmod +x $@
|
||||
|
||||
t: scaffold/t.c GNUmakefile
|
||||
rm -f $@
|
||||
gcc -nostdlib --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
|
||||
gcc -nostdlib -I. --std=gnu99 -m32 -g -o $@ '-DVERSION="0.4"' $<
|
||||
chmod +x $@
|
||||
|
||||
MAIN_C:=doc/examples/main.c
|
||||
|
|
|
@ -19,65 +19,7 @@
|
|||
*/
|
||||
|
||||
#if __GNUC__
|
||||
void
|
||||
exit (int code)
|
||||
{
|
||||
asm (
|
||||
"movl %0,%%ebx\n\t"
|
||||
"movl $1,%%eax\n\t"
|
||||
"int $0x80"
|
||||
: // no outputs "=" (r)
|
||||
: "" (code)
|
||||
);
|
||||
// not reached
|
||||
exit (0);
|
||||
}
|
||||
|
||||
void
|
||||
write (int fd, char const* s, int n)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_write, fd, s, n));
|
||||
asm (
|
||||
"mov %0,%%ebx\n\t"
|
||||
"mov %1,%%ecx\n\t"
|
||||
"mov %2,%%edx\n\t"
|
||||
|
||||
"mov $0x4, %%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
: // no outputs "=" (r)
|
||||
: "" (fd), "" (s), "" (n)
|
||||
: "eax", "ebx", "ecx", "edx"
|
||||
);
|
||||
}
|
||||
|
||||
#define STDOUT 1
|
||||
|
||||
typedef long size_t;
|
||||
size_t
|
||||
strlen (char const* s)
|
||||
{
|
||||
int i = 0;
|
||||
while (s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
puts (char const* s)
|
||||
{
|
||||
//write (STDOUT, s, strlen (s));
|
||||
//int i = write (STDOUT, s, strlen (s));
|
||||
int i = strlen (s);
|
||||
write (1, s, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
strcmp (char const* a, char const* b)
|
||||
{
|
||||
while (*a && *b && *a == *b) {a++;b++;}
|
||||
return *a - *b;
|
||||
}
|
||||
#include "mlibc.c"
|
||||
#endif
|
||||
|
||||
int
|
||||
|
@ -90,27 +32,5 @@ main (int argc, char *argv[])
|
|||
}
|
||||
|
||||
#if __GNUC__
|
||||
void
|
||||
_start ()
|
||||
{
|
||||
// int r=main ();
|
||||
// exit (r);
|
||||
int r;
|
||||
asm (
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $8,%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $4,%%eax\n\t"
|
||||
"movzbl (%%eax),%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"call main\n\t"
|
||||
"movl %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: //no inputs "" (&main)
|
||||
);
|
||||
exit (r);
|
||||
}
|
||||
#include "mstart.c"
|
||||
#endif
|
||||
|
|
230
mlibc.c
Normal file
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)
|
||||
(cadr o))
|
||||
|
||||
;; (define (.statement o)
|
||||
;; (match o
|
||||
;; (('function name signature statement) statement)
|
||||
;; (_ #f)))
|
||||
|
||||
;; (define (statement->data o)
|
||||
;; (match o
|
||||
;; (('call 'puts ('arguments string)) (string->list string))
|
||||
;; (_ '())))
|
||||
|
||||
;; (define (statement->text o)
|
||||
;; (match o
|
||||
;; (('call 'puts ('arguments string)) (list (lambda (data) (i386:puts data (string-length string)))))
|
||||
;; (('return code) (list (lambda (data) (i386:exit code))))
|
||||
;; (_ '())))
|
||||
|
||||
(define (.statement o)
|
||||
(and (pair? o)
|
||||
(eq? (car o) 'function)
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
|
||||
;;; Code:
|
||||
|
||||
;;(define barf #f)
|
||||
|
||||
(cond-expand
|
||||
(guile-2
|
||||
(set-port-encoding! (current-output-port) "ISO-8859-1"))
|
||||
|
@ -36,7 +34,8 @@
|
|||
(mes-use-module (mes elf-util))
|
||||
(mes-use-module (mes pmatch))
|
||||
(mes-use-module (mes elf))
|
||||
(mes-use-module (mes libc-i386))
|
||||
(mes-use-module (mes as-i386))
|
||||
(mes-use-module (mes libc))
|
||||
(mes-use-module (mes optargs))))
|
||||
|
||||
(define (logf port string . rest)
|
||||
|
@ -363,8 +362,20 @@ _)))))
|
|||
(abs-declr (pointer)))
|
||||
,cast)
|
||||
((expr->arg info) cast))
|
||||
|
||||
(_
|
||||
(format (current-error-port) "SKIP: expr->arg=~s\n" o)
|
||||
;; (stderr "catch: expr->arg=~s\n" o)
|
||||
(let* ((info ((expr->accu info) o))
|
||||
(text (.text info)))
|
||||
(clone info
|
||||
#:text (append text
|
||||
(list (lambda (f g ta t d)
|
||||
(append
|
||||
(i386:accu-zero?)
|
||||
(i386:push-accu))))))))
|
||||
|
||||
(_
|
||||
(stderr "SKIP: expr->arg=~s\n" o)
|
||||
barf
|
||||
0)))))
|
||||
|
||||
|
@ -767,20 +778,33 @@ _)))))
|
|||
(accu ((expr->accu empty) a))
|
||||
(base ((expr->base empty) b)))
|
||||
(clone info #:text
|
||||
(append text
|
||||
(append text ;;FIXME:empty
|
||||
(.text accu)
|
||||
(.text base)
|
||||
(list (lambda (f g ta t d)
|
||||
(i386:accu%base)))))))
|
||||
|
||||
;; FIXME: c/p ast->info
|
||||
((eq ,a ,b)
|
||||
(let* ((base ((expr->base info) a))
|
||||
(empty (clone base #:text '()))
|
||||
(accu ((expr->accu empty) b)))
|
||||
(clone info #:text
|
||||
(append (.text base)
|
||||
(list (lambda (f g ta t d)
|
||||
(i386:push-base)))
|
||||
(.text accu)
|
||||
(i386:pop-accu)
|
||||
(list (lambda (f g ta t d)
|
||||
(i386:sub-base)))))))
|
||||
|
||||
;; FIXME: c/p ast->info
|
||||
((lt ,a ,b)
|
||||
(let* ((base ((expr->base info) a))
|
||||
(empty (clone base #:text '()))
|
||||
(accu ((expr->accu empty) b)))
|
||||
(clone info #:text
|
||||
(append text
|
||||
(.text base)
|
||||
(append (.text base)
|
||||
(.text accu)
|
||||
(list (lambda (f g ta t d)
|
||||
(i386:base-sub)))))))
|
||||
|
@ -1187,7 +1211,7 @@ _)))))
|
|||
(locals (cons (make-local name type pointer id) locals)))
|
||||
locals))
|
||||
|
||||
;;(stderr "\n ast->info=~s\n" o)
|
||||
;; (stderr "\n ast->info=~s\n" o)
|
||||
;; (stderr " globals[~a=>~a]: ~a\n" (length globals) (length (append-map cdr globals)) (map (lambda (s) (if (string? s) (string-delete #\newline s))) (map car globals)))
|
||||
;; (stderr " text=~a\n" text)
|
||||
;; (stderr " info=~a\n" info)
|
||||
|
@ -2325,155 +2349,6 @@ _)))))
|
|||
(if (null? elements) info
|
||||
(loop (cdr elements) ((ast->info info) (car elements)))))))
|
||||
|
||||
(define _start
|
||||
(let* ((argc-argv
|
||||
(string-append ".byte"
|
||||
" 0x89 0xe8" ; mov %ebp,%eax
|
||||
" 0x83 0xc0 0x08" ; add $0x8,%eax
|
||||
" 0x50" ; push %eax
|
||||
" 0x89 0xe8" ; mov %ebp,%eax
|
||||
" 0x83 0xc0 0x04" ; add $0x4,%eax
|
||||
" 0x0f 0xb6 0x00" ; movzbl (%eax),%eax
|
||||
" 0x50" ; push %eax
|
||||
))
|
||||
(ast (with-input-from-string
|
||||
|
||||
(string-append "int _start () {int i;asm(\"" argc-argv "\");i=main ();exit (i);}")
|
||||
parse-c99)))
|
||||
ast))
|
||||
|
||||
(define strlen
|
||||
(let* ((ast (with-input-from-string
|
||||
"
|
||||
int
|
||||
strlen (char const* s)
|
||||
{
|
||||
int i = 0;
|
||||
while (s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
"
|
||||
;;paredit:"
|
||||
parse-c99)))
|
||||
ast))
|
||||
|
||||
(define getchar
|
||||
(let* ((ast (with-input-from-string
|
||||
"
|
||||
int g_stdin;
|
||||
int
|
||||
getchar ()
|
||||
{
|
||||
char c;
|
||||
int r = read (g_stdin, &c, 1);
|
||||
//int r = read (0, &c, 1);
|
||||
if (r < 1) return -1;
|
||||
return c;
|
||||
}
|
||||
"
|
||||
;;paredit:"
|
||||
parse-c99)))
|
||||
ast))
|
||||
|
||||
(define putchar
|
||||
(let* ((ast (with-input-from-string
|
||||
"
|
||||
int
|
||||
putchar (int c)
|
||||
{
|
||||
//write (STDOUT, s, strlen (s));
|
||||
//int i = write (STDOUT, s, strlen (s));
|
||||
write (1, (char*)&c, 1);
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
;;paredit:"
|
||||
parse-c99)))
|
||||
ast))
|
||||
|
||||
(define eputs
|
||||
(let* ((ast (with-input-from-string
|
||||
"
|
||||
int
|
||||
eputs (char const* s)
|
||||
{
|
||||
//write (STDERR, s, strlen (s));
|
||||
//write (2, s, strlen (s));
|
||||
int i = strlen (s);
|
||||
write (2, s, i);
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
;;paredit:"
|
||||
parse-c99)))
|
||||
ast))
|
||||
|
||||
(define fputs
|
||||
(let* ((ast (with-input-from-string
|
||||
"
|
||||
int
|
||||
fputs (char const* s, int fd)
|
||||
{
|
||||
int i = strlen (s);
|
||||
write (fd, s, i);
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
;;paredit:"
|
||||
parse-c99)))
|
||||
ast))
|
||||
|
||||
(define puts
|
||||
(let* ((ast (with-input-from-string
|
||||
"
|
||||
int
|
||||
puts (char const* s)
|
||||
{
|
||||
//write (STDOUT, s, strlen (s));
|
||||
//int i = write (STDOUT, s, strlen (s));
|
||||
int i = strlen (s);
|
||||
write (1, s, i);
|
||||
return 0;
|
||||
}
|
||||
"
|
||||
;;paredit:"
|
||||
parse-c99)))
|
||||
ast))
|
||||
|
||||
(define strcmp
|
||||
(let* ((ast (with-input-from-string
|
||||
"
|
||||
int
|
||||
strcmp (char const* a, char const* b)
|
||||
{
|
||||
while (*a && *b && *a == *b)
|
||||
{
|
||||
a++;b++;
|
||||
}
|
||||
return *a - *b;
|
||||
}
|
||||
"
|
||||
;;paredit:"
|
||||
parse-c99)))
|
||||
ast))
|
||||
|
||||
(define i386:libc
|
||||
(list
|
||||
(cons "exit" (list i386:exit))
|
||||
(cons "open" (list i386:open))
|
||||
(cons "read" (list i386:read))
|
||||
(cons "write" (list i386:write))))
|
||||
|
||||
(define libc
|
||||
(list
|
||||
strlen
|
||||
getchar
|
||||
putchar
|
||||
eputs
|
||||
fputs
|
||||
puts
|
||||
strcmp))
|
||||
|
||||
(define (compile)
|
||||
(let* ((ast (mescc))
|
||||
(info (make <info>
|
||||
|
|
|
@ -29,7 +29,9 @@
|
|||
#:use-module (ice-9 pretty-print)
|
||||
#:use-module (mes elf)
|
||||
#:use-module (mes elf-util)
|
||||
#:use-module (mes as-i386)
|
||||
#:use-module (mes libc-i386)
|
||||
#:use-module (mes libc)
|
||||
#:use-module (nyacc lang c99 parser)
|
||||
#:export (compile))
|
||||
|
||||
|
|
418
module/mes/as-i386.mes
Normal file
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:
|
||||
|
||||
(define (i386:function-preamble)
|
||||
'(#x55 ; push %ebp
|
||||
#x89 #xe5)) ; mov %esp,%ebp
|
||||
|
||||
;; (define (i386:function-locals)
|
||||
;; '(#x83 #xec #x20)) ; sub $0x10,%esp -- 8 local vars
|
||||
|
||||
(define (i386:function-locals)
|
||||
'(#x83 #xec #x40)) ; sub $0x10,%esp -- 16 local vars
|
||||
|
||||
(define (i386:push-global-address o)
|
||||
(or o push-global-address)
|
||||
`(#x68 ,@(int->bv32 o))) ; push $0x<o>
|
||||
|
||||
(define (i386:push-global o)
|
||||
(or o push-global)
|
||||
`(#xa1 ,@(int->bv32 o) ; mov 0x804a000,%eax
|
||||
#x50)) ; push %eax
|
||||
|
||||
(define (i386:push-local n)
|
||||
(or n push-local)
|
||||
`(#xff #x75 ,(- 0 (* 4 n)))) ; pushl 0x<n>(%ebp)
|
||||
|
||||
(define (i386:push-local-address n)
|
||||
(or n push-local-address)
|
||||
`(#x8d #x45 ,(- 0 (* 4 n)) ; lea 0x<n>(%ebp),%eax
|
||||
#x50)) ; push %eax
|
||||
|
||||
(define (i386:push-local-de-ref n)
|
||||
(or n push-local-de-ref)
|
||||
`(#x8b #x45 ,(- 0 (* 4 n)) ; mov -0x<n>(%ebp),%eax
|
||||
#x0f #xb6 #x00 ; movzbl (%eax),%eax
|
||||
;;#x0f #xbe #xc0 ; movsbl %al,%eax ***FIXME BYTE****
|
||||
#x50)) ; push %eax
|
||||
|
||||
(define (i386:pop-accu)
|
||||
'(#x58)) ; pop %eax
|
||||
|
||||
(define (i386:push-accu)
|
||||
'(#x50)) ; push %eax
|
||||
|
||||
(define (i386:pop-base)
|
||||
'(#x5a)) ; pop %eax
|
||||
|
||||
(define (i386:push-base)
|
||||
'(#x52)) ; push %eax
|
||||
|
||||
(define (i386:ret)
|
||||
'(#xc9 ; leave
|
||||
#xc3)) ; ret
|
||||
|
||||
(define (i386:accu->base)
|
||||
'(#x89 #xc2)) ; mov %eax,%edx
|
||||
|
||||
(define (i386:accu->base-address)
|
||||
'(#x89 #x02)) ; mov %eax,%(edx)
|
||||
|
||||
(define (i386:byte-accu->base-address)
|
||||
'(#x88 #x02)) ; mov %al,%(edx)
|
||||
|
||||
(define (i386:accu->base-address+n n)
|
||||
(or n accu->base-address+n)
|
||||
`(#x89 #x42 ,n)) ; mov %eax,$0x<n>%(edx)
|
||||
|
||||
(define (i386:accu->local n)
|
||||
(or n accu->local)
|
||||
`(#x89 #x45 ,(- 0 (* 4 n)))) ; mov %eax,-<0xn>(%ebp)
|
||||
|
||||
(define (i386:base->local n)
|
||||
(or n base->local)
|
||||
`(#x89 #x55 ,(- 0 (* 4 n)))) ; mov %edx,-<0xn>(%ebp)
|
||||
|
||||
(define (i386:base->global n)
|
||||
(or n base->global)
|
||||
`(#x89 #x15 ,@(int->bv32 n))) ; mov %edx,0x0
|
||||
|
||||
(define (i386:accu->global n)
|
||||
(or n accu->global)
|
||||
`(#xa3 ,@(int->bv32 n))) ; mov %eax,0x0
|
||||
|
||||
(define (i386:accu->global-address n)
|
||||
(or n accu->global-address)
|
||||
`(#x8b #x15 ,@(int->bv32 n) ; mov 0x<n>,%edx
|
||||
#x89 #x02 )) ; mov %eax,(%edx)
|
||||
|
||||
(define (i386:accu-zero?)
|
||||
'(#x85 #xc0)) ; cmpl %eax,%eax
|
||||
|
||||
(define (i386:accu-non-zero?)
|
||||
(append '(#x85 #xc0) ; cmpl %eax,%eax
|
||||
(i386:xor-zf)))
|
||||
|
||||
(define (i386:accu-shl n)
|
||||
(or n accu:shl n)
|
||||
`(#xc1 #xe0 ,n)) ; shl $0x8,%eax
|
||||
|
||||
(define (i386:accu+accu)
|
||||
'(#x01 #xc0)) ; add %eax,%eax
|
||||
|
||||
(define (i386:accu+base)
|
||||
`(#x01 #xd0)) ; add %edx,%eax
|
||||
|
||||
(define (i386:accu+value v)
|
||||
(or v accu+value)
|
||||
`(#x05 ,@(int->bv32 v))) ; add %eax,%eax
|
||||
|
||||
(define (i386:accu-base)
|
||||
`(#x29 #xd0)) ; sub %edx,%eax
|
||||
|
||||
(define (i386:accu/base)
|
||||
'(#x86 #xd3 ; mov %edx,%ebx
|
||||
#x31 #xd2 ; xor %edx,%edx
|
||||
#xf7 #xf3)) ; div %ebx
|
||||
|
||||
(define (i386:accu%base)
|
||||
'(#x86 #xd3 ; mov %edx,%ebx
|
||||
#x31 #xd2 ; xor %edx,%edx
|
||||
#xf7 #xf3 ; div %ebx
|
||||
#x89 #xd0)) ; mov %edx,%eax
|
||||
|
||||
(define (i386:base->accu)
|
||||
'(#x89 #xd0)) ; mov %edx,%eax
|
||||
|
||||
(define (i386:local->accu n)
|
||||
(or n local->accu)
|
||||
`(#x8b #x45 ,(- 0 (* 4 n)))) ; mov -<0xn>(%ebp),%eax
|
||||
|
||||
(define (i386:local-address->accu n)
|
||||
(or n ladd)
|
||||
`(#x8d #x45 ,(- 0 (* 4 n)))) ; lea 0x<n>(%ebp),%eax
|
||||
|
||||
(define (i386:local-ptr->accu n)
|
||||
(or n local-ptr->accu)
|
||||
`(#x89 #xe8 ; mov %ebp,%eax
|
||||
#x83 #xc0 ,(- 0 (* 4 n)))) ; add $0x<n>,%eax
|
||||
|
||||
(define (i386:byte-local->accu n)
|
||||
(or n byte-local->accu)
|
||||
`(#x0f #xb6 #x45 ,(- 0 (* 4 n)))) ; movzbl 0x<n>(%ebp),%eax
|
||||
|
||||
(define (i386:local->base n)
|
||||
(or n local->base)
|
||||
`(#x8b #x55 ,(- 0 (* 4 n)))) ; mov -<0xn>(%ebp),%edx
|
||||
|
||||
(define (i386:local-address->base n) ;; DE-REF
|
||||
(or n local-address->base)
|
||||
`(#x8d #x55 ,(- 0 (* 4 n)))) ; lea 0x<n>(%ebp),%edx
|
||||
|
||||
(define (i386:local-ptr->base n)
|
||||
(or n local-ptr->base)
|
||||
`(#x89 #xea ; mov %ebp,%edx
|
||||
#x83 #xc2 ,(- 0 (* 4 n)))) ; add $0x<n>,%edx
|
||||
|
||||
(define (i386:global->base n)
|
||||
(or n global->base)
|
||||
`(#xba ,@(int->bv32 n))) ; mov $<n>,%edx
|
||||
|
||||
(define (i386:global-address->accu n)
|
||||
(or n global-address->accu)
|
||||
`(#xa1 ,@(int->bv32 n))) ; mov 0x<n>,%eax
|
||||
|
||||
(define (i386:global-address->base n)
|
||||
(or n global-address->base)
|
||||
`(#x8b #x15 ,@(int->bv32 n))) ; mov 0x<n>,%edx
|
||||
|
||||
(define (i386:byte-base-mem->accu)
|
||||
'(#x01 #xd0 ; add %edx,%eax
|
||||
#x0f #xb6 #x00)) ; movzbl (%eax),%eax
|
||||
|
||||
(define (i386:byte-mem->accu)
|
||||
'(#x0f #xb6 #x00)) ; movzbl (%eax),%eax
|
||||
|
||||
(define (i386:byte-mem->base)
|
||||
'(#x0f #xb6 #x10)) ; movzbl (%eax),%edx
|
||||
|
||||
(define (i386:base-mem->accu)
|
||||
'(#x01 #xd0 ; add %edx,%eax
|
||||
#x8b #x00)) ; mov (%eax),%eax
|
||||
|
||||
(define (i386:mem->accu)
|
||||
'(#x8b #x00)) ; mov (%eax),%eax
|
||||
|
||||
(define (i386:mem+n->accu n)
|
||||
`(#x8b #x40 ,n)) ; mov 0x<n>(%eax),%eax
|
||||
|
||||
(define (i386:base-mem+n->accu n)
|
||||
(or n base-mem+n->accu)
|
||||
`(#x01 #xd0 ; add %edx,%eax
|
||||
#x8b #x40 ,n)) ; mov <n>(%eax),%eax
|
||||
|
||||
(define (i386:value->accu v)
|
||||
(or v urg:value->accu)
|
||||
`(#xb8 ,@(int->bv32 v))) ; mov $<v>,%eax
|
||||
|
||||
(define (i386:value->accu-address v)
|
||||
`(#xc7 #x00 ,@(int->bv32 v))) ; movl $0x<v>,(%eax)
|
||||
|
||||
(define (i386:value->accu-address+n n v)
|
||||
(or v urg:value->accu-address+n)
|
||||
`(#xc7 #x40 ,n ,@(int->bv32 v))) ; movl $<v>,0x<n>(%eax)
|
||||
|
||||
(define (i386:base->accu-address)
|
||||
'(#x89 #x10)) ; mov %edx,(%eax)
|
||||
|
||||
(define (i386:base-address->accu-address)
|
||||
'(#x8b #x0a ; mov (%edx),%ecx
|
||||
#x89 #x08)) ; mov %ecx,(%eax)
|
||||
|
||||
(define (i386:accu+n n)
|
||||
`(#x83 #xc0 ,n)) ; add $0x00,%eax
|
||||
|
||||
(define (i386:base+n n)
|
||||
`(#x83 #xc2 ,n)) ; add $0x00,%edx
|
||||
|
||||
(define (i386:byte-base->accu-address)
|
||||
'(#x88 #x10)) ; mov %dl,(%eax)
|
||||
|
||||
(define (i386:byte-base->accu-address+n n)
|
||||
(or n byte-base->accu-address+n)
|
||||
`(#x88 #x50 ,n)) ; mov %dl,0x<n>(%eax)
|
||||
|
||||
(define (i386:value->base v)
|
||||
(or v urg:value->base)
|
||||
`(#xba ,@(int->bv32 v))) ; mov $<v>,%edx
|
||||
|
||||
(define (i386:local-add n v)
|
||||
(or n urg:local-add)
|
||||
`(#x83 #x45 ,(- 0 (* 4 n)) ,v)) ; addl $<v>,0x<n>(%ebp)
|
||||
|
||||
(define (i386:global-add n v)
|
||||
(or n urg:global-add)
|
||||
`(#x83 #x05 ,@(int->bv32 n) ,v)) ; addl $<v>,0x<n>
|
||||
|
||||
(define (i386:global->accu o)
|
||||
(or o urg:global->accu)
|
||||
`(#xb8 ,@(int->bv32 o))) ; mov $<>,%eax
|
||||
|
||||
(define (i386:value->global n v)
|
||||
(or n value->global)
|
||||
`(#xc7 #x05 ,@(int->bv32 n) ; movl $<v>,(<n>)
|
||||
,@(int->bv32 v)))
|
||||
|
||||
(define (i386:value->local n v)
|
||||
(or n value->local)
|
||||
`(#xc7 #x45 ,(- 0 (* 4 n)) ; movl $<v>,0x<n>(%ebp)
|
||||
,@(int->bv32 v)))
|
||||
|
||||
(define (i386:local-test n v)
|
||||
(or n local-test)
|
||||
`(#x83 #x7d ,(- 0 (* 4 n)) ,v)) ; cmpl $<v>,0x<n>(%ebp)
|
||||
|
||||
(define (i386:call f g ta t d address n)
|
||||
(or address urg:call)
|
||||
`(#xe8 ,@(int->bv32 (- address 5)) ; call relative $00
|
||||
#x83 #xc4 ,(* n 4))) ; add $00,%esp
|
||||
|
||||
(define (i386:call-accu f g ta t d n)
|
||||
`(,@(i386:push-accu)
|
||||
,@(i386:pop-accu)
|
||||
#xff #xd0 ; call *%eax
|
||||
#x83 #xc4 ,(* n 4))) ; add $00,%esp
|
||||
|
||||
(define (i386:accu-not)
|
||||
`(#x0f #x94 #xc0 ; sete %al
|
||||
#x0f #xb6 #xc0)) ; movzbl %al,%eax
|
||||
|
||||
(define (i386:xor-accu v)
|
||||
(or n urg:xor-accu)
|
||||
`(#x35 ,@(int->bv32 v))) ;xor $0xff,%eax
|
||||
|
||||
(define (i386:xor-zf)
|
||||
'(#x9f ; lahf
|
||||
#x80 #xf4 #x40 ; xor $0x40,%ah
|
||||
#x9e)) ; sahf
|
||||
|
||||
(define (i386:accu-cmp-value v)
|
||||
`(#x83 #xf8 ,v)) ; cmp $<v>,%eax
|
||||
|
||||
(define (i386:accu-test)
|
||||
'(#x85 #xc0)) ; test %eax,%eax
|
||||
|
||||
(define (i386:Xjump n)
|
||||
(or n urg:Xjump)
|
||||
`(#xe9 ,@(int->bv32 (if (>= n 0) n (- n 5))))) ; jmp . + <n>
|
||||
|
||||
(define (i386:XXjump n)
|
||||
(or n urg:XXjump)
|
||||
`(#xe9 ,@(int->bv32 n))) ; jmp . + <n>
|
||||
|
||||
(define (i386:Xjump-nz n)
|
||||
(or n urg:Xjump-nz)
|
||||
`(#x0f #x85 ,@(int->bv32 n))) ; jnz . + <n>
|
||||
|
||||
(define (i386:Xjump-z n)
|
||||
(or n urg:Xjump-z)
|
||||
`(#x0f #x84 ,@(int->bv32 n))) ; jz . + <n>
|
||||
|
||||
(define (i386:jump n) ;;FIXME: NEED THIS WEIRDNESS for t.c
|
||||
(when (or (> n #x80) (< n #x-80))
|
||||
(format (current-error-port) "JUMP n=~a\n" n)
|
||||
barf)
|
||||
`(#xeb ,(if (>= n 0) (- n 2) (- n 2)))) ; jmp <n>
|
||||
|
||||
(define (i386:jump-c n)
|
||||
(when (or (> n #x80) (< n #x-80))
|
||||
(format (current-error-port) "JUMP n=~a\n" n)
|
||||
barf)
|
||||
`(#x72 ,(if (>= n 0) n (- n 2)))) ; jc <n>
|
||||
|
||||
(define (i386:Xjump-c n)
|
||||
(or n urg:Xjump-c)
|
||||
`(#x0f #x82 ,@(int->bv32 n))) ; jc <n>
|
||||
|
||||
(define (i386:jump-cz n)
|
||||
(when (or (> n #x80) (< n #x-80))
|
||||
(format (current-error-port) "JUMP n=~a\n" n)
|
||||
barf)
|
||||
`(#x76 ,(if (>= n 0) n (- n 2)))) ; jna <n>
|
||||
|
||||
(define (i386:jump-ncz n)
|
||||
(when (or (> n #x80) (< n #x-80))
|
||||
(format (current-error-port) "JUMP-ncz n=~a\n" n)
|
||||
barf)
|
||||
`(#x77 ,(if (>= n 0) n (- n 2)))) ; ja <n>
|
||||
|
||||
(define (i386:jump-nc n)
|
||||
(when (or (> n #x80) (< n #x-80))
|
||||
(format (current-error-port) "JUMP-nc n=~a\n" n)
|
||||
barf)
|
||||
`(#x73 ,(if (>= n 0) n (- n 2)))) ; jnc <n>
|
||||
|
||||
(define (i386:Xjump-nc n)
|
||||
(or n urg:Xjump-nc)
|
||||
`(#x0f #x83 ,@(int->bv32 n))) ; jnc <n>
|
||||
|
||||
(define (i386:jump-z n)
|
||||
(when (or (> n #x80) (< n #x-80))
|
||||
(format (current-error-port) "JUMP-z n=~a\n" n)
|
||||
barf)
|
||||
`(#x74 ,(if (>= n 0) n (- n 2)))) ; jz <n>
|
||||
|
||||
(define (i386:jump-nz n)
|
||||
(when (or (> n #x80) (< n #x-80))
|
||||
(format (current-error-port) "JUMP-nz n=~a\n" n)
|
||||
barf)
|
||||
`(#x75 ,(if (>= n 0) n (- n 2)))) ; jnz <n>
|
||||
|
||||
(define (i386:test-jump-z n)
|
||||
(when (or (> n #x80) (< n #x-80))
|
||||
(format (current-error-port) "JUMP-z n=~a\n" n)
|
||||
barf)
|
||||
`(#x85 #xc0 ; test %eax,%eax
|
||||
#x74 ,(if (>= n 0) n (- n 4)))) ; jz <n>
|
||||
|
||||
(define (i386:jump-byte-nz n)
|
||||
(when (or (> n #x80) (< n #x-80))
|
||||
(format (current-error-port) "JUMP-byte-nz n=~a\n" n)
|
||||
barf)
|
||||
`(#x84 #xc0 ; test %al,%al
|
||||
#x75 ,(if (>= n 0) n (- n 4)))) ; jne <n>
|
||||
|
||||
(define (i386:jump-byte-z n)
|
||||
(when (or (> n #x80) (< n #x-80))
|
||||
(format (current-error-port) "JUMP-byte-z n=~a\n" n)
|
||||
barf)
|
||||
`(#x84 #xc0 ; test %al,%al
|
||||
#x74 ,(if (>= n 0) n (- n 4)))) ; jne <n>
|
||||
|
||||
(define (i386:byte-test-base)
|
||||
`(#x38 #xc2)) ; cmp %al,%dl
|
||||
|
||||
(define (i386:test-base)
|
||||
`(#x39 #xd0)) ; cmp %edx,%eax
|
||||
|
||||
(define (i386:byte-sub-base)
|
||||
`(#x28 #xd0)) ; sub %dl,%al
|
||||
|
||||
(define (i386:byte-base-sub)
|
||||
`(#x28 #xd0)) ; sub %al,%dl
|
||||
|
||||
(define (i386:sub-base)
|
||||
`(#x29 #xd0)) ; sub %edx,%eax
|
||||
|
||||
(define (i386:base-sub)
|
||||
`(#x29 #xc2)) ; sub %eax,%edx
|
||||
|
||||
;;; libc bits
|
||||
(define (i386:exit f g ta t d)
|
||||
`(
|
||||
#x5b ; pop %ebx
|
||||
|
@ -466,44 +79,20 @@
|
|||
#xc3 ; ret
|
||||
))
|
||||
|
||||
#!
|
||||
08048121 <strcmp>:
|
||||
8048121: 55 push %ebp
|
||||
8048122: 89 e5 mov %esp,%ebp
|
||||
8048124: 83 ec 10 sub $0x10,%esp
|
||||
8048127: eb 08 jmp 8048131 <strcmp+0x10>
|
||||
(define (i386:_start)
|
||||
(string-append ".byte"
|
||||
" 0x89 0xe8" ; mov %ebp,%eax
|
||||
" 0x83 0xc0 0x08" ; add $0x8,%eax
|
||||
" 0x50" ; push %eax
|
||||
" 0x89 0xe8" ; mov %ebp,%eax
|
||||
" 0x83 0xc0 0x04" ; add $0x4,%eax
|
||||
" 0x0f 0xb6 0x00" ; movzbl (%eax),%eax
|
||||
" 0x50" ; push %eax
|
||||
))
|
||||
|
||||
<body>
|
||||
8048129: 83 45 08 01 addl $0x1,0x8(%ebp)
|
||||
804812d: 83 45 0c 01 addl $0x1,0xc(%ebp)
|
||||
|
||||
<test> *a
|
||||
8048131: 8b 45 08 mov 0x8(%ebp),%eax
|
||||
8048134: 0f b6 00 movzbl (%eax),%eax
|
||||
8048137: 84 c0 test %al,%al
|
||||
8048139: 74 08 je 8048143 <strcmp+0x22>
|
||||
|
||||
<test1> *b
|
||||
804813b: 8b 45 0c mov 0xc(%ebp),%eax
|
||||
804813e: 0f b6 00 movzbl (%eax),%eax
|
||||
8048141: 84 c0 test %al,%al
|
||||
8048143: 74 10 je 8048155 <strcmp+0x34>
|
||||
|
||||
<test2> *a == *b
|
||||
8048145: 8b 45 08 mov 0x8(%ebp),%eax
|
||||
8048148: 0f b6 10 movzbl (%eax),%edx
|
||||
804814b: 8b 45 0c mov 0xc(%ebp),%eax
|
||||
804814e: 0f b6 00 movzbl (%eax),%eax
|
||||
8048151: 38 c2 cmp %al,%dl
|
||||
8048153: 84 c0 test %al,%al
|
||||
8048155: 75 d2 jne 8048129 <strcmp+0x8>
|
||||
|
||||
|
||||
8048157: 8b 45 08 mov 0x8(%ebp),%eax
|
||||
804815a: 0f b6 10 movzbl (%eax),%edx
|
||||
804815d: 8b 45 0c mov 0xc(%ebp),%eax
|
||||
8048160: 0f b6 00 movzbl (%eax),%eax
|
||||
8048163: 28 d0 sub %dl,%al
|
||||
8048165: c9 leave
|
||||
8048166: c3 ret
|
||||
!#
|
||||
(define i386:libc
|
||||
(list
|
||||
(cons "exit" (list i386:exit))
|
||||
(cons "open" (list i386:open))
|
||||
(cons "read" (list i386:read))
|
||||
(cons "write" (list i386:write))))
|
||||
|
|
|
@ -25,124 +25,7 @@
|
|||
;;; Code:
|
||||
|
||||
(define-module (mes libc-i386)
|
||||
#:use-module (srfi srfi-1)
|
||||
#:use-module (mes elf)
|
||||
#:export (
|
||||
i386:accu-not
|
||||
i386:accu-cmp-value
|
||||
i386:accu->base
|
||||
i386:accu->base-address
|
||||
i386:accu->base-address+n
|
||||
i386:accu->global
|
||||
i386:accu->global-address
|
||||
i386:accu->local
|
||||
i386:accu-non-zero?
|
||||
i386:accu-test
|
||||
i386:accu-zero?
|
||||
i386:accu+accu
|
||||
i386:accu+base
|
||||
i386:accu+value
|
||||
i386:accu/base
|
||||
i386:accu%base
|
||||
i386:accu-base
|
||||
i386:accu-shl
|
||||
i386:base-sub
|
||||
i386:base->accu
|
||||
i386:base->accu-address
|
||||
i386:byte-accu->base-address
|
||||
i386:base->global
|
||||
i386:base->local
|
||||
i386:base-mem->accu
|
||||
i386:byte-base-sub
|
||||
i386:byte-base->accu-address
|
||||
i386:byte-base->accu-address+n
|
||||
i386:byte-base-mem->accu
|
||||
i386:local-address->accu
|
||||
i386:byte-local->accu
|
||||
i386:byte-mem->accu
|
||||
i386:base-mem+n->accu
|
||||
i386:byte-mem->base
|
||||
i386:byte-test-base
|
||||
i386:byte-sub-base
|
||||
i386:call
|
||||
i386:call-accu
|
||||
i386:formal
|
||||
i386:function-locals
|
||||
i386:function-preamble
|
||||
i386:global-add
|
||||
i386:global->accu
|
||||
i386:global->base
|
||||
i386:global-address->accu
|
||||
i386:global-address->base
|
||||
i386:jump
|
||||
i386:jump
|
||||
i386:jump-byte-nz
|
||||
i386:jump-byte-z
|
||||
i386:jump-c
|
||||
i386:jump-cz
|
||||
i386:jump-le
|
||||
i386:jump-nc
|
||||
i386:jump-ncz
|
||||
i386:jump-nz
|
||||
i386:jump-z
|
||||
i386:local->accu
|
||||
i386:local->base
|
||||
i386:local-add
|
||||
i386:local-address->accu
|
||||
i386:local-ptr->accu
|
||||
i386:local-ptr->base
|
||||
i386:local-address->base
|
||||
i386:local-test
|
||||
i386:mem->accu
|
||||
i386:mem+n->accu
|
||||
i386:pop-accu
|
||||
i386:push-accu
|
||||
i386:pop-base
|
||||
i386:push-base
|
||||
i386:push-global
|
||||
i386:push-global-address
|
||||
i386:push-local
|
||||
i386:push-local-de-ref
|
||||
i386:push-local-address
|
||||
i386:ret
|
||||
i386:ret-local
|
||||
i386:sub-base
|
||||
i386:test-base
|
||||
i386:test-jump-z
|
||||
i386:value->accu
|
||||
i386:value->accu-address
|
||||
i386:value->accu-address+n
|
||||
i386:value->global
|
||||
i386:value->local
|
||||
i386:value->base
|
||||
i386:xor-accu
|
||||
i386:xor-zf
|
||||
|
||||
;; long jump
|
||||
i386:Xjump
|
||||
i386:Xjump
|
||||
i386:Xjump-c
|
||||
i386:Xjump-nc
|
||||
i386:Xjump-nz
|
||||
i386:Xjump-z
|
||||
|
||||
i386:XXjump
|
||||
|
||||
i386:accu+n
|
||||
i386:base+n
|
||||
i386:base-address->accu-address
|
||||
|
||||
;; libc
|
||||
i386:exit
|
||||
i386:open
|
||||
i386:read
|
||||
i386:write
|
||||
))
|
||||
|
||||
(cond-expand
|
||||
(guile-2)
|
||||
(guile
|
||||
(use-modules (ice-9 syncase)))
|
||||
(mes))
|
||||
#:export (i386:libc
|
||||
i386:_start))
|
||||
|
||||
(include-from-path "mes/libc-i386.mes")
|
||||
|
|
223
module/mes/libc.mes
Normal file
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/>.
|
||||
*/
|
||||
|
||||
#if __GNUC__
|
||||
#include "mlibc.c"
|
||||
#endif
|
||||
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
|
||||
|
||||
#define MES_MINI 1
|
||||
#define FIXED_PRIMITIVES 0
|
||||
|
||||
|
@ -35,209 +40,6 @@
|
|||
char arena[2000];
|
||||
//char buf0[400];
|
||||
|
||||
int g_stdin = 0;
|
||||
|
||||
#if __GNUC__
|
||||
typedef long size_t;
|
||||
void *malloc (size_t i);
|
||||
int open (char const *s, int mode);
|
||||
int read (int fd, void* buf, size_t n);
|
||||
void write (int fd, char const* s, int n);
|
||||
|
||||
void
|
||||
exit (int code)
|
||||
{
|
||||
asm (
|
||||
"movl %0,%%ebx\n\t"
|
||||
"movl $1,%%eax\n\t"
|
||||
"int $0x80"
|
||||
: // no outputs "=" (r)
|
||||
: "" (code)
|
||||
);
|
||||
// not reached
|
||||
exit (0);
|
||||
}
|
||||
|
||||
char const*
|
||||
getenv (char const* p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
read (int fd, void* buf, size_t n)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_write, fd, s, n));
|
||||
asm (
|
||||
"movl %1,%%ebx\n\t"
|
||||
"movl %2,%%ecx\n\t"
|
||||
"movl %3,%%edx\n\t"
|
||||
"movl $0x3,%%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
"mov %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: "" (fd), "" (buf), "" (n)
|
||||
: "eax", "ebx", "ecx", "edx"
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
open (char const *s, int mode)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_open, mode));
|
||||
asm (
|
||||
"mov %1,%%ebx\n\t"
|
||||
"mov %2,%%ecx\n\t"
|
||||
"mov $0x5,%%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
"mov %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: "" (s), "" (mode)
|
||||
: "eax", "ebx", "ecx"
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
getchar ()
|
||||
{
|
||||
char c;
|
||||
int r = read (g_stdin, &c, 1);
|
||||
if (r < 1) return -1;
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
write (int fd, char const* s, int n)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_write, fd, s, n));
|
||||
asm (
|
||||
"mov %0,%%ebx\n\t"
|
||||
"mov %1,%%ecx\n\t"
|
||||
"mov %2,%%edx\n\t"
|
||||
|
||||
"mov $0x4, %%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
: // no outputs "=" (r)
|
||||
: "" (fd), "" (s), "" (n)
|
||||
: "eax", "ebx", "ecx", "edx"
|
||||
);
|
||||
}
|
||||
|
||||
int
|
||||
putchar (int c)
|
||||
{
|
||||
//write (STDOUT, s, strlen (s));
|
||||
//int i = write (STDOUT, s, strlen (s));
|
||||
write (1, (char*)&c, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
malloc (size_t size)
|
||||
{
|
||||
int *n;
|
||||
int len = size + sizeof (size);
|
||||
//n = mmap (0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 );
|
||||
*n = len;
|
||||
return (void*)(n+1);
|
||||
}
|
||||
|
||||
void
|
||||
free (void *p)
|
||||
{
|
||||
int *n = (int*)p-1;
|
||||
//munmap ((void*)p, *n);
|
||||
}
|
||||
|
||||
#define EOF -1
|
||||
#define STDIN 0
|
||||
#define STDOUT 1
|
||||
#define STDERR 2
|
||||
|
||||
size_t
|
||||
strlen (char const* s)
|
||||
{
|
||||
int i = 0;
|
||||
while (s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
strcmp (char const* a, char const* b)
|
||||
{
|
||||
while (*a && *b && *a == *b) {a++;b++;}
|
||||
return *a - *b;
|
||||
}
|
||||
|
||||
int
|
||||
puts (char const* s)
|
||||
{
|
||||
//write (STDOUT, s, strlen (s));
|
||||
//int i = write (STDOUT, s, strlen (s));
|
||||
int i = strlen (s);
|
||||
write (1, s, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eputs (char const* s)
|
||||
{
|
||||
//write (STDERR, s, strlen (s));
|
||||
//int i = write (STDERR, s, strlen (s));
|
||||
int i = strlen (s);
|
||||
write (2, s, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char const*
|
||||
itoa (int x)
|
||||
{
|
||||
static char buf[10];
|
||||
char *p = buf+9;
|
||||
*p-- = 0;
|
||||
|
||||
int sign = x < 0;
|
||||
if (sign)
|
||||
x = -x;
|
||||
|
||||
do
|
||||
{
|
||||
*p-- = '0' + (x % 10);
|
||||
x = x / 10;
|
||||
} while (x);
|
||||
|
||||
if (sign)
|
||||
*p-- = '-';
|
||||
|
||||
return p+1;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
assert_fail (char* s)
|
||||
{
|
||||
eputs ("assert fail:");
|
||||
#if __GNUC__
|
||||
eputs (s);
|
||||
#endif
|
||||
eputs ("\n");
|
||||
#if __GNUC__
|
||||
*((int*)0) = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __GNUC__
|
||||
#define assert(x) ((x) ? (void)0 : assert_fail ("boo:" #x))
|
||||
#else
|
||||
//#define assert(x) ((x) ? (void)0 : assert_fail ("boo:" #x))
|
||||
#define assert(x) ((x) ? (void)0 : assert_fail (0))
|
||||
#endif
|
||||
|
||||
typedef int SCM;
|
||||
|
||||
#if __GNUC__
|
||||
|
@ -278,32 +80,6 @@ struct function {
|
|||
|
||||
struct scm *g_cells = arena;
|
||||
|
||||
//scm *g_news = 0;
|
||||
|
||||
// struct scm scm_nil = {SPECIAL, "()"};
|
||||
// struct scm scm_f = {SPECIAL, "#f"};
|
||||
// struct scm scm_t = {SPECIAL, "#t"};
|
||||
// struct scm_dot = {SPECIAL, "."};
|
||||
// struct scm_arrow = {SPECIAL, "=>"};
|
||||
// struct scm_undefined = {SPECIAL, "*undefined*"};
|
||||
// struct scm_unspecified = {SPECIAL, "*unspecified*"};
|
||||
// struct scm_closure = {SPECIAL, "*closure*"};
|
||||
// struct scm_circular = {SPECIAL, "*circular*"};
|
||||
// struct scm_begin = {SPECIAL, "*begin*"};
|
||||
|
||||
// struct scm_vm_apply = {SPECIAL, "core:apply"};
|
||||
// struct scm_vm_apply2 = {SPECIAL, "*vm-apply2*"};
|
||||
|
||||
// struct scm_vm_eval = {SPECIAL, "core:eval"};
|
||||
|
||||
// struct scm_vm_begin = {SPECIAL, "*vm-begin*"};
|
||||
// //scm scm_vm_begin_read_input_file = {SPECIAL, "*vm-begin-read-input-file*"};
|
||||
// struct scm_vm_begin2 = {SPECIAL, "*vm-begin2*"};
|
||||
|
||||
// struct scm_vm_return = {SPECIAL, "*vm-return*"};
|
||||
|
||||
// //#include "mes.symbols.h"
|
||||
|
||||
#define cell_nil 1
|
||||
#define cell_f 2
|
||||
#define cell_t 3
|
||||
|
@ -341,37 +117,25 @@ struct function g_functions[5];
|
|||
int g_function = 0;
|
||||
|
||||
|
||||
#if __GNUC__
|
||||
//FIXME
|
||||
SCM make_cell (SCM type, SCM car, SCM cdr);
|
||||
#endif
|
||||
struct function fun_make_cell = {&make_cell,3,"make-cell"};
|
||||
struct scm scm_make_cell = {TFUNCTION,0,0};
|
||||
//, "make-cell", 0};
|
||||
SCM cell_make_cell;
|
||||
|
||||
#if __GNUC__
|
||||
//FIXME
|
||||
SCM cons (SCM x, SCM y);
|
||||
#endif
|
||||
struct function fun_cons = {&cons,2,"cons"};
|
||||
struct scm scm_cons = {TFUNCTION,0,0};
|
||||
// "cons", 0};
|
||||
SCM cell_cons;
|
||||
|
||||
#if __GNUC__
|
||||
//FIXME
|
||||
SCM car (SCM x);
|
||||
#endif
|
||||
struct function fun_car = {&car,1,"car"};
|
||||
struct scm scm_car = {TFUNCTION,0,0};
|
||||
// "car", 0};
|
||||
SCM cell_car;
|
||||
|
||||
#if __GNUC__
|
||||
//FIXME
|
||||
SCM cdr (SCM x);
|
||||
#endif
|
||||
struct function fun_cdr = {&cdr,1,"cdr"};
|
||||
struct scm scm_cdr = {TFUNCTION,0,0};
|
||||
// "cdr", 0};
|
||||
|
@ -469,11 +233,11 @@ tmp_num2_ (int x)
|
|||
SCM
|
||||
cons (SCM x, SCM y)
|
||||
{
|
||||
#if 0
|
||||
puts ("cons x=");
|
||||
#if __GNUC__
|
||||
puts (itoa (x));
|
||||
#endif
|
||||
puts ("\n");
|
||||
#endif
|
||||
VALUE (tmp_num) = PAIR;
|
||||
return make_cell (tmp_num, x, y);
|
||||
}
|
||||
|
@ -481,11 +245,11 @@ cons (SCM x, SCM y)
|
|||
SCM
|
||||
car (SCM x)
|
||||
{
|
||||
#if 0
|
||||
puts ("car x=");
|
||||
#if __GNUC__
|
||||
puts (itoa (x));
|
||||
#endif
|
||||
puts ("\n");
|
||||
#endif
|
||||
#if MES_MINI
|
||||
//Nyacc
|
||||
//assert ("!car");
|
||||
|
@ -498,11 +262,11 @@ car (SCM x)
|
|||
SCM
|
||||
cdr (SCM x)
|
||||
{
|
||||
#if 0
|
||||
puts ("cdr x=");
|
||||
#if __GNUC__
|
||||
puts (itoa (x));
|
||||
#endif
|
||||
puts ("\n");
|
||||
#endif
|
||||
#if MES_MINI
|
||||
//Nyacc
|
||||
//assert ("!cdr");
|
||||
|
@ -1290,25 +1054,5 @@ main (int argc, char *argv[])
|
|||
}
|
||||
|
||||
#if __GNUC__
|
||||
void
|
||||
_start ()
|
||||
{
|
||||
int r;
|
||||
asm (
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $8,%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $4,%%eax\n\t"
|
||||
"movzbl (%%eax),%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"call main\n\t"
|
||||
"movl %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: //no inputs "" (&main)
|
||||
);
|
||||
exit (r);
|
||||
}
|
||||
#include "mstart.c"
|
||||
#endif
|
||||
|
|
131
scaffold/m.c
131
scaffold/m.c
|
@ -18,115 +18,10 @@
|
|||
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
int g_stdin = 0;
|
||||
typedef long size_t;
|
||||
|
||||
#if __GNUC__
|
||||
void
|
||||
exit (int code)
|
||||
{
|
||||
asm (
|
||||
"movl %0,%%ebx\n\t"
|
||||
"movl $1,%%eax\n\t"
|
||||
"int $0x80"
|
||||
: // no outputs "=" (r)
|
||||
: "" (code)
|
||||
);
|
||||
// not reached
|
||||
exit (0);
|
||||
}
|
||||
|
||||
int
|
||||
read (int fd, void* buf, size_t n)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_write, fd, s, n));
|
||||
asm (
|
||||
"movl %1,%%ebx\n\t"
|
||||
"movl %2,%%ecx\n\t"
|
||||
"movl %3,%%edx\n\t"
|
||||
"movl $0x3,%%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
"mov %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: "" (fd), "" (buf), "" (n)
|
||||
: "eax", "ebx", "ecx", "edx"
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
open (char const *s, int mode)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_open, mode));
|
||||
asm (
|
||||
"mov %1,%%ebx\n\t"
|
||||
"mov %2,%%ecx\n\t"
|
||||
"mov $0x5,%%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
"mov %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: "" (s), "" (mode)
|
||||
: "eax", "ebx", "ecx"
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
getchar ()
|
||||
{
|
||||
char c;
|
||||
int r = read (g_stdin, &c, 1);
|
||||
if (r < 1) return -1;
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
write (int fd, char const* s, int n)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_write, fd, s, n));
|
||||
asm (
|
||||
"mov %0,%%ebx\n\t"
|
||||
"mov %1,%%ecx\n\t"
|
||||
"mov %2,%%edx\n\t"
|
||||
|
||||
"mov $0x4, %%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
: // no outputs "=" (r)
|
||||
: "" (fd), "" (s), "" (n)
|
||||
: "eax", "ebx", "ecx", "edx"
|
||||
);
|
||||
}
|
||||
|
||||
int
|
||||
putchar (int c)
|
||||
{
|
||||
//write (STDOUT, s, strlen (s));
|
||||
//int i = write (STDOUT, s, strlen (s));
|
||||
write (1, (char*)&c, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t
|
||||
strlen (char const* s)
|
||||
{
|
||||
int i = 0;
|
||||
while (s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
puts (char const* s)
|
||||
{
|
||||
//write (STDOUT, s, strlen (s));
|
||||
//int i = write (STDOUT, s, strlen (s));
|
||||
int i = strlen (s);
|
||||
write (1, s, i);
|
||||
return 0;
|
||||
}
|
||||
#include "mlibc.c"
|
||||
#endif
|
||||
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
|
@ -141,25 +36,5 @@ main (int argc, char *argv[])
|
|||
}
|
||||
|
||||
#if __GNUC__
|
||||
void
|
||||
_start ()
|
||||
{
|
||||
int r;
|
||||
asm (
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $8,%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $4,%%eax\n\t"
|
||||
"movzbl (%%eax),%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"call main\n\t"
|
||||
"movl %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: //no inputs "" (&main)
|
||||
);
|
||||
exit (r);
|
||||
}
|
||||
#include "mstart.c"
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,12 @@
|
|||
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if __GNUC__
|
||||
#include "mlibc.c"
|
||||
#endif
|
||||
#define assert(x) ((x) ? (void)0 : assert_fail(#x))
|
||||
|
||||
|
||||
#define MES_MINI 1
|
||||
|
||||
#if __GNUC__
|
||||
|
@ -30,168 +36,6 @@
|
|||
#define NYACC2 nyacc2
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
typedef long size_t;
|
||||
void *malloc (size_t i);
|
||||
int open (char const *s, int mode);
|
||||
int read (int fd, int n);
|
||||
void write (int fd, char const* s, int n);
|
||||
|
||||
void
|
||||
exit (int code)
|
||||
{
|
||||
asm (
|
||||
"movl %0,%%ebx\n\t"
|
||||
"movl $1,%%eax\n\t"
|
||||
"int $0x80"
|
||||
: // no outputs "=" (r)
|
||||
: "" (code)
|
||||
);
|
||||
// not reached
|
||||
exit (0);
|
||||
}
|
||||
|
||||
char const*
|
||||
getenv (char const* p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
open (char const *s, int mode)
|
||||
{
|
||||
//return syscall (SYS_open, s, mode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
read (int fd, int n)
|
||||
{
|
||||
//syscall (SYS_read, 1, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
write (int fd, char const* s, int n)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_write, fd, s, n));
|
||||
asm (
|
||||
"mov %0,%%ebx\n\t"
|
||||
"mov %1,%%ecx\n\t"
|
||||
"mov %2,%%edx\n\t"
|
||||
|
||||
"mov $0x4, %%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
: // no outputs "=" (r)
|
||||
: "" (fd), "" (s), "" (n)
|
||||
: "eax", "ebx", "ecx", "edx"
|
||||
);
|
||||
}
|
||||
|
||||
void *
|
||||
malloc (size_t size)
|
||||
{
|
||||
int *n;
|
||||
int len = size + sizeof (size);
|
||||
//n = mmap (0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 );
|
||||
*n = len;
|
||||
return (void*)(n+1);
|
||||
}
|
||||
|
||||
void
|
||||
free (void *p)
|
||||
{
|
||||
int *n = (int*)p-1;
|
||||
//munmap ((void*)p, *n);
|
||||
}
|
||||
|
||||
#define EOF -1
|
||||
#define STDIN 0
|
||||
#define STDOUT 1
|
||||
#define STDERR 2
|
||||
|
||||
//#include <stdio.h>
|
||||
//#include <string.h>
|
||||
//#include <stdlib.h>
|
||||
|
||||
int g_stdin;
|
||||
|
||||
size_t
|
||||
strlen (char const* s)
|
||||
{
|
||||
int i = 0;
|
||||
while (s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
strcmp (char const* a, char const* b)
|
||||
{
|
||||
while (*a && *b && *a == *b) {a++;b++;}
|
||||
return *a - *b;
|
||||
}
|
||||
|
||||
int
|
||||
getchar ()
|
||||
{
|
||||
return read (g_stdin, 1);
|
||||
}
|
||||
|
||||
int
|
||||
puts (char const* s)
|
||||
{
|
||||
//write (STDOUT, s, strlen (s));
|
||||
//int i = write (STDOUT, s, strlen (s));
|
||||
int i = strlen (s);
|
||||
write (1, s, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eputs (char const* s)
|
||||
{
|
||||
//write (STDERR, s, strlen (s));
|
||||
//int i = write (STDERR, s, strlen (s));
|
||||
int i = strlen (s);
|
||||
write (2, s, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char const*
|
||||
itoa (int x)
|
||||
{
|
||||
static char buf[10];
|
||||
char *p = buf+9;
|
||||
*p-- = 0;
|
||||
|
||||
int sign = x < 0;
|
||||
if (sign)
|
||||
x = -x;
|
||||
|
||||
do
|
||||
{
|
||||
*p-- = '0' + (x % 10);
|
||||
x = x / 10;
|
||||
} while (x);
|
||||
|
||||
if (sign)
|
||||
*p-- = '-';
|
||||
|
||||
return p+1;
|
||||
}
|
||||
|
||||
void
|
||||
assert_fail (char* s)
|
||||
{
|
||||
eputs ("assert fail:");
|
||||
eputs (s);
|
||||
eputs ("\n");
|
||||
*((int*)0) = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define assert(x) ((x) ? (void)0 : assert_fail(#x))
|
||||
typedef int SCM;
|
||||
|
||||
#if __GNUC__
|
||||
|
@ -267,25 +111,5 @@ main (int argc, char *argv[])
|
|||
}
|
||||
|
||||
#if __GNUC__
|
||||
void
|
||||
_start ()
|
||||
{
|
||||
int r;
|
||||
asm (
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $8,%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $4,%%eax\n\t"
|
||||
"movzbl (%%eax),%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"call main\n\t"
|
||||
"movl %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: //no inputs "" (&main)
|
||||
);
|
||||
exit (r);
|
||||
}
|
||||
#include "mstart.c"
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,11 @@
|
|||
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if __GNUC__
|
||||
#include "mlibc.c"
|
||||
#endif
|
||||
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
|
||||
|
||||
#define MES_MINI 1
|
||||
#define FIXED_PRIMITIVES 0
|
||||
|
||||
|
@ -35,220 +40,6 @@
|
|||
int ARENA_SIZE = 1200000;
|
||||
char arena[1200000];
|
||||
|
||||
int g_stdin = 0;
|
||||
|
||||
#if __GNUC__
|
||||
typedef long size_t;
|
||||
void *malloc (size_t i);
|
||||
int open (char const *s, int mode);
|
||||
int read (int fd, void* buf, size_t n);
|
||||
void write (int fd, char const* s, int n);
|
||||
|
||||
void
|
||||
exit (int code)
|
||||
{
|
||||
asm (
|
||||
"movl %0,%%ebx\n\t"
|
||||
"movl $1,%%eax\n\t"
|
||||
"int $0x80"
|
||||
: // no outputs "=" (r)
|
||||
: "" (code)
|
||||
);
|
||||
// not reached
|
||||
exit (0);
|
||||
}
|
||||
|
||||
char const*
|
||||
getenv (char const* p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
read (int fd, void* buf, size_t n)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_write, fd, s, n));
|
||||
asm (
|
||||
"movl %1,%%ebx\n\t"
|
||||
"movl %2,%%ecx\n\t"
|
||||
"movl %3,%%edx\n\t"
|
||||
"movl $0x3,%%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
"mov %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: "" (fd), "" (buf), "" (n)
|
||||
: "eax", "ebx", "ecx", "edx"
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
open (char const *s, int mode)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_open, mode));
|
||||
asm (
|
||||
"mov %1,%%ebx\n\t"
|
||||
"mov %2,%%ecx\n\t"
|
||||
"mov $0x5,%%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
"mov %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: "" (s), "" (mode)
|
||||
: "eax", "ebx", "ecx"
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
int puts (char const*);
|
||||
char const* itoa (int);
|
||||
|
||||
int
|
||||
getchar ()
|
||||
{
|
||||
char c;
|
||||
int r = read (g_stdin, &c, 1);
|
||||
if (r < 1) return -1;
|
||||
int i = c;
|
||||
if (i < 0) i += 256;
|
||||
return i;
|
||||
}
|
||||
|
||||
void
|
||||
write (int fd, char const* s, int n)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_write, fd, s, n));
|
||||
asm (
|
||||
"mov %0,%%ebx\n\t"
|
||||
"mov %1,%%ecx\n\t"
|
||||
"mov %2,%%edx\n\t"
|
||||
|
||||
"mov $0x4, %%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
: // no outputs "=" (r)
|
||||
: "" (fd), "" (s), "" (n)
|
||||
: "eax", "ebx", "ecx", "edx"
|
||||
);
|
||||
}
|
||||
|
||||
int
|
||||
putchar (int c)
|
||||
{
|
||||
//write (STDOUT, s, strlen (s));
|
||||
//int i = write (STDOUT, s, strlen (s));
|
||||
write (1, (char*)&c, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
malloc (size_t size)
|
||||
{
|
||||
int *n;
|
||||
int len = size + sizeof (size);
|
||||
//n = mmap (0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 );
|
||||
*n = len;
|
||||
return (void*)(n+1);
|
||||
}
|
||||
|
||||
void
|
||||
free (void *p)
|
||||
{
|
||||
int *n = (int*)p-1;
|
||||
//munmap ((void*)p, *n);
|
||||
}
|
||||
|
||||
#define EOF -1
|
||||
#define STDIN 0
|
||||
#define STDOUT 1
|
||||
#define STDERR 2
|
||||
|
||||
size_t
|
||||
strlen (char const* s)
|
||||
{
|
||||
int i = 0;
|
||||
while (s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
strcmp (char const* a, char const* b)
|
||||
{
|
||||
while (*a && *b && *a == *b) {a++;b++;}
|
||||
return *a - *b;
|
||||
}
|
||||
|
||||
int
|
||||
puts (char const* s)
|
||||
{
|
||||
//write (STDOUT, s, strlen (s));
|
||||
//int i = write (STDOUT, s, strlen (s));
|
||||
int i = strlen (s);
|
||||
write (1, s, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eputs (char const* s)
|
||||
{
|
||||
//write (STDERR, s, strlen (s));
|
||||
//int i = write (STDERR, s, strlen (s));
|
||||
int i = strlen (s);
|
||||
write (2, s, i);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
char itoa_buf[10];
|
||||
|
||||
char const*
|
||||
itoa (int x)
|
||||
{
|
||||
//static char itoa_buf[10];
|
||||
//char *p = buf+9;
|
||||
char *p = itoa_buf;
|
||||
p += 9;
|
||||
*p-- = 0;
|
||||
|
||||
//int sign = x < 0;
|
||||
int sign;
|
||||
sign = x < 0;
|
||||
if (sign)
|
||||
x = -x;
|
||||
|
||||
do
|
||||
{
|
||||
*p-- = '0' + (x % 10);
|
||||
x = x / 10;
|
||||
} while (x);
|
||||
|
||||
if (sign)
|
||||
*p-- = '-';
|
||||
|
||||
return p+1;
|
||||
}
|
||||
|
||||
void
|
||||
assert_fail (char* s)
|
||||
{
|
||||
eputs ("assert fail:");
|
||||
#if __GNUC__
|
||||
eputs (s);
|
||||
#endif
|
||||
eputs ("\n");
|
||||
#if __GNUC__
|
||||
*((int*)0) = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __GNUC__
|
||||
#define assert(x) ((x) ? (void)0 : assert_fail ("boo:" #x))
|
||||
#else
|
||||
//#define assert(x) ((x) ? (void)0 : assert_fail ("boo:" #x))
|
||||
#define assert(x) ((x) ? (void)0 : assert_fail (0))
|
||||
#endif
|
||||
|
||||
typedef int SCM;
|
||||
|
||||
int g_debug = 0;
|
||||
|
@ -415,7 +206,9 @@ int g_function = 0;
|
|||
SCM
|
||||
alloc (int n)
|
||||
{
|
||||
#if __GNUC__
|
||||
assert (g_free + n < ARENA_SIZE);
|
||||
#endif
|
||||
SCM x = g_free;
|
||||
g_free += n;
|
||||
return x;
|
||||
|
@ -427,7 +220,9 @@ SCM
|
|||
make_cell (SCM type, SCM car, SCM cdr)
|
||||
{
|
||||
SCM x = alloc (1);
|
||||
#if __GNUC__
|
||||
assert (TYPE (type) == TNUMBER);
|
||||
#endif
|
||||
TYPE (x) = VALUE (type);
|
||||
if (VALUE (type) == TCHAR || VALUE (type) == TNUMBER) {
|
||||
if (car) CAR (x) = CAR (car);
|
||||
|
@ -557,7 +352,9 @@ SCM
|
|||
append2 (SCM x, SCM y)
|
||||
{
|
||||
if (x == cell_nil) return y;
|
||||
#if __GNUC__
|
||||
assert (TYPE (x) == TPAIR);
|
||||
#endif
|
||||
return cons (car (x), append2 (cdr (x), y));
|
||||
}
|
||||
|
||||
|
@ -616,7 +413,9 @@ assq_ref_env (SCM x, SCM a)
|
|||
SCM
|
||||
set_car_x (SCM x, SCM e)
|
||||
{
|
||||
#if __GNUC__
|
||||
assert (TYPE (x) == TPAIR);
|
||||
#endif
|
||||
CAR (x) = e;
|
||||
return cell_unspecified;
|
||||
}
|
||||
|
@ -1068,8 +867,10 @@ SCM
|
|||
list_of_char_equal_p (SCM a, SCM b)
|
||||
{
|
||||
while (a != cell_nil && b != cell_nil && VALUE (car (a)) == VALUE (car (b))) {
|
||||
#if __GNUC__
|
||||
assert (TYPE (car (a)) == TCHAR);
|
||||
assert (TYPE (car (b)) == TCHAR);
|
||||
#endif
|
||||
a = cdr (a);
|
||||
b = cdr (b);
|
||||
}
|
||||
|
@ -1132,7 +933,9 @@ write_byte (SCM x) ///((arity . n))
|
|||
int fd = 1;
|
||||
if (TYPE (p) == TPAIR && TYPE (car (p)) == TNUMBER) fd = VALUE (car (p));
|
||||
//FILE *f = fd == 1 ? stdout : stderr;
|
||||
#if __GNUC__
|
||||
assert (TYPE (c) == TNUMBER || TYPE (c) == TCHAR);
|
||||
#endif
|
||||
// fputc (VALUE (c), f);
|
||||
char cc = VALUE (c);
|
||||
write (1, (char*)&cc, fd);
|
||||
|
@ -1454,25 +1257,5 @@ main (int argc, char *argv[])
|
|||
}
|
||||
|
||||
#if __GNUC__
|
||||
void
|
||||
_start ()
|
||||
{
|
||||
int r;
|
||||
asm (
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $8,%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $4,%%eax\n\t"
|
||||
"movzbl (%%eax),%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"call main\n\t"
|
||||
"movl %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: //no inputs "" (&main)
|
||||
);
|
||||
exit (r);
|
||||
}
|
||||
#include "mstart.c"
|
||||
#endif
|
||||
|
|
131
scaffold/t.c
131
scaffold/t.c
|
@ -19,75 +19,9 @@
|
|||
*/
|
||||
|
||||
#if __GNUC__
|
||||
void
|
||||
exit (int code)
|
||||
{
|
||||
asm (
|
||||
"movl %0,%%ebx\n\t"
|
||||
"movl $1,%%eax\n\t"
|
||||
"int $0x80"
|
||||
: // no outputs "=" (r)
|
||||
: "" (code)
|
||||
);
|
||||
// not reached
|
||||
exit (0);
|
||||
}
|
||||
|
||||
void
|
||||
write (int fd, char const* s, int n)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_write, fd, s, n));
|
||||
asm (
|
||||
"mov %0,%%ebx\n\t"
|
||||
"mov %1,%%ecx\n\t"
|
||||
"mov %2,%%edx\n\t"
|
||||
|
||||
"mov $0x4,%%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
: // no outputs "=" (r)
|
||||
: "" (fd), "" (s), "" (n)
|
||||
: "eax", "ebx", "ecx", "edx"
|
||||
);
|
||||
}
|
||||
|
||||
#define STDOUT 1
|
||||
|
||||
typedef long size_t;
|
||||
size_t
|
||||
strlen (char const* s)
|
||||
{
|
||||
int i = 0;
|
||||
while (s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
puts (char const* s)
|
||||
{
|
||||
//write (STDOUT, s, strlen (s));
|
||||
//int i = write (STDOUT, s, strlen (s));
|
||||
int i = strlen (s);
|
||||
write (1, s, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
putchar (int c)
|
||||
{
|
||||
//write (STDOUT, s, strlen (s));
|
||||
//int i = write (STDOUT, s, strlen (s));
|
||||
write (1, (char*)&c, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
strcmp (char const* a, char const* b)
|
||||
{
|
||||
while (*a && *b && *a == *b) {a++;b++;}
|
||||
return *a - *b;
|
||||
}
|
||||
#include "mlibc.c"
|
||||
#endif
|
||||
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
|
||||
|
||||
struct scm {
|
||||
int type;
|
||||
|
@ -136,36 +70,6 @@ struct scm scm_fun = {TFUNCTION,0,0};
|
|||
SCM cell_fun;
|
||||
|
||||
#if 1
|
||||
|
||||
char itoa_buf[10];
|
||||
|
||||
char const*
|
||||
itoa (int x)
|
||||
{
|
||||
//static char itoa_buf[10];
|
||||
//char *p = buf+9;
|
||||
char *p = itoa_buf;
|
||||
p += 9;
|
||||
*p-- = 0;
|
||||
|
||||
//int sign = x < 0;
|
||||
int sign;
|
||||
sign = x < 0;
|
||||
if (sign)
|
||||
x = -x;
|
||||
|
||||
do
|
||||
{
|
||||
*p-- = '0' + (x % 10);
|
||||
x = x / 10;
|
||||
} while (x);
|
||||
|
||||
if (sign)
|
||||
*p-- = '-';
|
||||
|
||||
return p+1;
|
||||
}
|
||||
|
||||
int
|
||||
add (int a, int b)
|
||||
{
|
||||
|
@ -546,6 +450,12 @@ test (char *p)
|
|||
puts ("t: (f) ?\n");
|
||||
(f) ? exit (1) : 1;
|
||||
|
||||
puts ("t: assert (1) ?\n");
|
||||
assert (1);
|
||||
|
||||
puts ("t: assert (f==0) ?\n");
|
||||
assert (f==0);
|
||||
|
||||
puts ("t: p[0] != 't'\n");
|
||||
if (p[0] != 't') return p[0];
|
||||
|
||||
|
@ -758,28 +668,5 @@ main (int argc, char *argv[])
|
|||
}
|
||||
|
||||
#if __GNUC__
|
||||
void
|
||||
_start ()
|
||||
{
|
||||
// int r=main ();
|
||||
// exit (r);
|
||||
int r;
|
||||
asm (
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $8,%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $4,%%eax\n\t"
|
||||
"movzbl (%%eax),%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"call main\n\t"
|
||||
|
||||
"movl %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: //no inputs "" (&main)
|
||||
);
|
||||
exit (r);
|
||||
}
|
||||
#include "mstart.c"
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,11 @@
|
|||
* along with Mes. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if __GNUC__
|
||||
#include "mlibc.c"
|
||||
#endif
|
||||
#define assert(x) ((x) ? (void)0 : assert_fail (#x))
|
||||
|
||||
#define MES_MINI 1
|
||||
|
||||
#if __GNUC__
|
||||
|
@ -33,210 +38,6 @@
|
|||
|
||||
char arena[200];
|
||||
|
||||
int g_stdin = 0;
|
||||
|
||||
#if __GNUC__
|
||||
typedef long size_t;
|
||||
void *malloc (size_t i);
|
||||
int open (char const *s, int mode);
|
||||
int read (int fd, void* buf, size_t n);
|
||||
void write (int fd, char const* s, int n);
|
||||
|
||||
void
|
||||
exit (int code)
|
||||
{
|
||||
asm (
|
||||
"movl %0,%%ebx\n\t"
|
||||
"movl $1,%%eax\n\t"
|
||||
"int $0x80"
|
||||
: // no outputs "=" (r)
|
||||
: "" (code)
|
||||
);
|
||||
// not reached
|
||||
exit (0);
|
||||
}
|
||||
|
||||
char const*
|
||||
getenv (char const* p)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
read (int fd, void* buf, size_t n)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_write, fd, s, n));
|
||||
asm (
|
||||
"movl %1,%%ebx\n\t"
|
||||
"movl %2,%%ecx\n\t"
|
||||
"movl %3,%%edx\n\t"
|
||||
"movl $0x3,%%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
"mov %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: "" (fd), "" (buf), "" (n)
|
||||
: "eax", "ebx", "ecx", "edx"
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
open (char const *s, int mode)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_open, mode));
|
||||
asm (
|
||||
"mov %1,%%ebx\n\t"
|
||||
"mov %2,%%ecx\n\t"
|
||||
"mov $0x5,%%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
"mov %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: "" (s), "" (mode)
|
||||
: "eax", "ebx", "ecx"
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
int
|
||||
getchar ()
|
||||
{
|
||||
char c;
|
||||
int r = read (g_stdin, &c, 1);
|
||||
if (r < 1) return -1;
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
write (int fd, char const* s, int n)
|
||||
{
|
||||
int r;
|
||||
//syscall (SYS_write, fd, s, n));
|
||||
asm (
|
||||
"mov %0,%%ebx\n\t"
|
||||
"mov %1,%%ecx\n\t"
|
||||
"mov %2,%%edx\n\t"
|
||||
|
||||
"mov $0x4, %%eax\n\t"
|
||||
"int $0x80\n\t"
|
||||
: // no outputs "=" (r)
|
||||
: "" (fd), "" (s), "" (n)
|
||||
: "eax", "ebx", "ecx", "edx"
|
||||
);
|
||||
}
|
||||
|
||||
int
|
||||
putchar (int c)
|
||||
{
|
||||
//write (STDOUT, s, strlen (s));
|
||||
//int i = write (STDOUT, s, strlen (s));
|
||||
write (1, (char*)&c, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *
|
||||
malloc (size_t size)
|
||||
{
|
||||
int *n;
|
||||
int len = size + sizeof (size);
|
||||
//n = mmap (0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 );
|
||||
*n = len;
|
||||
return (void*)(n+1);
|
||||
}
|
||||
|
||||
void
|
||||
free (void *p)
|
||||
{
|
||||
int *n = (int*)p-1;
|
||||
//munmap ((void*)p, *n);
|
||||
}
|
||||
|
||||
#define EOF -1
|
||||
#define STDIN 0
|
||||
#define STDOUT 1
|
||||
#define STDERR 2
|
||||
|
||||
size_t
|
||||
strlen (char const* s)
|
||||
{
|
||||
int i = 0;
|
||||
while (s[i]) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
int
|
||||
strcmp (char const* a, char const* b)
|
||||
{
|
||||
while (*a && *b && *a == *b) {a++;b++;}
|
||||
return *a - *b;
|
||||
}
|
||||
|
||||
int
|
||||
puts (char const* s)
|
||||
{
|
||||
//write (STDOUT, s, strlen (s));
|
||||
//int i = write (STDOUT, s, strlen (s));
|
||||
int i = strlen (s);
|
||||
write (1, s, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
eputs (char const* s)
|
||||
{
|
||||
//write (STDERR, s, strlen (s));
|
||||
//int i = write (STDERR, s, strlen (s));
|
||||
int i = strlen (s);
|
||||
write (2, s, i);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char const*
|
||||
itoa (int x)
|
||||
{
|
||||
static char buf[10];
|
||||
char *p = buf+9;
|
||||
*p-- = 0;
|
||||
|
||||
int sign = x < 0;
|
||||
if (sign)
|
||||
x = -x;
|
||||
|
||||
do
|
||||
{
|
||||
*p-- = '0' + (x % 10);
|
||||
x = x / 10;
|
||||
} while (x);
|
||||
|
||||
if (sign)
|
||||
*p-- = '-';
|
||||
|
||||
return p+1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
assert_fail (char* s)
|
||||
{
|
||||
eputs ("assert fail:");
|
||||
#if __GNUC__
|
||||
eputs (s);
|
||||
#endif
|
||||
eputs ("\n");
|
||||
#if __GNUC__
|
||||
*((int*)0) = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if __GNUC__
|
||||
#define assert(x) ((x) ? (void)0 : assert_fail ("boo:" #x))
|
||||
#else
|
||||
//#define assert(x) ((x) ? (void)0 : assert_fail ("boo:" #x))
|
||||
#define assert(x) ((x) ? (void)0 : assert_fail (0))
|
||||
#endif
|
||||
|
||||
typedef int SCM;
|
||||
|
||||
#if __GNUC__
|
||||
|
@ -567,26 +368,5 @@ main (int argc, char *argv[])
|
|||
}
|
||||
|
||||
#if __GNUC__
|
||||
void
|
||||
_start ()
|
||||
{
|
||||
int r;
|
||||
asm (
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $8,%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"mov %%ebp,%%eax\n\t"
|
||||
"addl $4,%%eax\n\t"
|
||||
"movzbl (%%eax),%%eax\n\t"
|
||||
"push %%eax\n\t"
|
||||
|
||||
"call main\n\t"
|
||||
"movl %%eax,%0\n\t"
|
||||
: "=r" (r)
|
||||
: //no inputs "" (&main)
|
||||
);
|
||||
exit (r);
|
||||
}
|
||||
#include "mstart.c"
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in a new issue