mescc: Mes C Library: Add x86_64 libc support.
* include/linux/x86_64/syscall.h: New file. * include/linux/x86/syscall.h: New file. * lib/linux/x86_64-mes-gcc/mes.c: New file. * lib/linux/x86-mes/mes.c: Rename from lib/linux/mes.c. * lib/linux/x86-mes-gcc/mes.c: Rename from lib/linux/gcc.c. * lib/linux/libc.c: Update includes. (waitpid)[__x86_64__]: Use wait4. * build-aux/build-cc.sh: Build libc too. * lib/x86-mes/x86.M1 (mov____0x8(%ebp),%esi): New macro.
This commit is contained in:
parent
46e0641e9c
commit
5a6d8c21e0
|
@ -24,7 +24,7 @@ set -e
|
||||||
. ${srcdest}build-aux/trace.sh
|
. ${srcdest}build-aux/trace.sh
|
||||||
|
|
||||||
# cc64
|
# cc64
|
||||||
LIBC=${LIBC-c-mini}
|
LIBC=${LIBC-c}
|
||||||
|
|
||||||
# native
|
# native
|
||||||
trace "SNARF gc.c" ${srcdest}build-aux/mes-snarf.scm src/gc.c
|
trace "SNARF gc.c" ${srcdest}build-aux/mes-snarf.scm src/gc.c
|
||||||
|
@ -52,7 +52,7 @@ ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/linux/x86_64-mes-gcc/c
|
||||||
# ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/linux/x86_64/crti
|
# ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/linux/x86_64/crti
|
||||||
# ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/linux/x86_64/crtn
|
# ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/linux/x86_64/crtn
|
||||||
ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libc-mini
|
ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libc-mini
|
||||||
# ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libc
|
ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libc
|
||||||
# ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libgetopt
|
# ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libgetopt
|
||||||
# ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libc+tcc
|
# ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libc+tcc
|
||||||
# ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libtcc1
|
# ARCHDIR=1 NOLINK=1 sh ${srcdest}build-aux/cc64-mes.sh lib/libtcc1
|
||||||
|
|
38
include/linux/x86/syscall.h
Normal file
38
include/linux/x86/syscall.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/* -*-comment-start: "//";comment-end:""-*-
|
||||||
|
* GNU Mes --- Maxwell Equations of Software
|
||||||
|
* Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
||||||
|
*
|
||||||
|
* This file is part of GNU Mes.
|
||||||
|
*
|
||||||
|
* GNU 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.
|
||||||
|
*
|
||||||
|
* GNU 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 GNU Mes. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef __MES_LINUX_X86_SYSCALL_H
|
||||||
|
#define __MES_LINUX_X86_SYSCALL_H 1
|
||||||
|
|
||||||
|
// #define SYS_exit 0x01
|
||||||
|
// #define SYS_write 0x04
|
||||||
|
|
||||||
|
#define SYS_fork 0x02
|
||||||
|
#define SYS_read 0x03
|
||||||
|
#define SYS_open 0x05
|
||||||
|
#define SYS_waitpid 0x07
|
||||||
|
#define SYS_wait4 0x72
|
||||||
|
#define SYS_execve 0x0b
|
||||||
|
#define SYS_chmod 0x0f
|
||||||
|
#define SYS_access 0x21
|
||||||
|
#define SYS_brk 0x2d
|
||||||
|
#define SYS_ioctl 0x36
|
||||||
|
#define SYS_fsync 0x76
|
||||||
|
|
||||||
|
#endif // __MES_LINUX_X86_SYSCALL_H
|
38
include/linux/x86_64/syscall.h
Normal file
38
include/linux/x86_64/syscall.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/* -*-comment-start: "//";comment-end:""-*-
|
||||||
|
* GNU Mes --- Maxwell Equations of Software
|
||||||
|
* Copyright © 2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
||||||
|
*
|
||||||
|
* This file is part of GNU Mes.
|
||||||
|
*
|
||||||
|
* GNU 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.
|
||||||
|
*
|
||||||
|
* GNU 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 GNU Mes. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
#ifndef __MES_LINUX_X86_64_SYSCALL_H
|
||||||
|
#define __MES_LINUX_X86_64_SYSCALL_H 1
|
||||||
|
|
||||||
|
// #define SYS_write 0x01
|
||||||
|
// #define SYS_exit 0x3c
|
||||||
|
|
||||||
|
#define SYS_fork 0x39
|
||||||
|
#define SYS_read 0x00
|
||||||
|
#define SYS_open 0x02
|
||||||
|
//#define SYS_waitpid
|
||||||
|
#define SYS_wait4 0x3d
|
||||||
|
#define SYS_execve 0x3a
|
||||||
|
#define SYS_chmod 0x5a
|
||||||
|
#define SYS_access 0x15
|
||||||
|
#define SYS_brk 0x0c
|
||||||
|
#define SYS_ioctl 0x10
|
||||||
|
#define SYS_fsync 0x4a
|
||||||
|
|
||||||
|
#endif // __MES_LINUX_X86_64_SYSCALL_H
|
|
@ -221,7 +221,7 @@ _fdungetc_p (int fd)
|
||||||
return _ungetc_pos > -1;
|
return _ungetc_pos > -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if POSIX || __x86_64__
|
#if POSIX
|
||||||
#define STDERR 2
|
#define STDERR 2
|
||||||
int
|
int
|
||||||
eputs (char const* s)
|
eputs (char const* s)
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
int
|
int
|
||||||
link (char const *old_name, char const *new_name)
|
link (char const *old_name, char const *new_name)
|
||||||
{
|
{
|
||||||
return _sys_call2 (SYS_link, (int)old_name, (int)new_name);
|
return _sys_call2 (SYS_link, (long)old_name, (long)new_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
pid_t
|
pid_t
|
||||||
|
@ -59,25 +59,25 @@ getuid ()
|
||||||
int
|
int
|
||||||
kill (pid_t pid, int signum)
|
kill (pid_t pid, int signum)
|
||||||
{
|
{
|
||||||
return _sys_call2 (SYS_kill, (int)pid, (int)signum);
|
return _sys_call2 (SYS_kill, (long)pid, (long)signum);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
rename (char const *old_name, char const *new_name)
|
rename (char const *old_name, char const *new_name)
|
||||||
{
|
{
|
||||||
return _sys_call2 (SYS_rename, (int)old_name, (int)new_name);
|
return _sys_call2 (SYS_rename, (long)old_name, (long)new_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mkdir (char const *file_name, mode_t mode)
|
mkdir (char const *file_name, mode_t mode)
|
||||||
{
|
{
|
||||||
return _sys_call2 (SYS_mkdir, (int)file_name, (int)mode);
|
return _sys_call2 (SYS_mkdir, (long)file_name, (long)mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
dup (int old)
|
dup (int old)
|
||||||
{
|
{
|
||||||
return _sys_call1 (SYS_dup, (int)old);
|
return _sys_call1 (SYS_dup, (long)old);
|
||||||
}
|
}
|
||||||
|
|
||||||
gid_t
|
gid_t
|
||||||
|
@ -103,7 +103,7 @@ fcntl (int filedes, int command, ...)
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, command);
|
va_start (ap, command);
|
||||||
int data = va_arg (ap, int);
|
int data = va_arg (ap, int);
|
||||||
int r = _sys_call3 (SYS_fcntl, (int)filedes, (int)command, (int)data);
|
int r = _sys_call3 (SYS_fcntl, (long)filedes, (long)command, (long)data);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -111,43 +111,43 @@ fcntl (int filedes, int command, ...)
|
||||||
int
|
int
|
||||||
pipe (int filedes[2])
|
pipe (int filedes[2])
|
||||||
{
|
{
|
||||||
return _sys_call1 (SYS_pipe, (int)filedes);
|
return _sys_call1 (SYS_pipe, (long)filedes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
dup2 (int old, int new)
|
dup2 (int old, int new)
|
||||||
{
|
{
|
||||||
return _sys_call2 (SYS_dup2, (int)old, (int)new);
|
return _sys_call2 (SYS_dup2, (long)old, (long)new);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
getrusage (int processes, struct rusage *rusage)
|
getrusage (int processes, struct rusage *rusage)
|
||||||
{
|
{
|
||||||
return _sys_call2 (SYS_getrusage, (int)processes, (int)rusage);
|
return _sys_call2 (SYS_getrusage, (long)processes, (long)rusage);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
lstat (char const *file_name, struct stat *statbuf)
|
lstat (char const *file_name, struct stat *statbuf)
|
||||||
{
|
{
|
||||||
return _sys_call2 (SYS_lstat, (int)file_name, (int)statbuf);
|
return _sys_call2 (SYS_lstat, (long)file_name, (long)statbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nanosleep (const struct timespec *requested_time,
|
nanosleep (const struct timespec *requested_time,
|
||||||
struct timespec *remaining)
|
struct timespec *remaining)
|
||||||
{
|
{
|
||||||
return _sys_call2 (SYS_nanosleep, (int)requested_time, (int)remaining);
|
return _sys_call2 (SYS_nanosleep, (long)requested_time, (long)remaining);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
setitimer (int which, struct itimerval const *new,
|
setitimer (int which, struct itimerval const *new,
|
||||||
struct itimerval *old)
|
struct itimerval *old)
|
||||||
{
|
{
|
||||||
return _sys_call3 (SYS_setitimer, (int)which, (int)new, (int)old);
|
return _sys_call3 (SYS_setitimer, (long)which, (long)new, (long)old);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
fstat (int fd, struct stat *statbuf)
|
fstat (int fd, struct stat *statbuf)
|
||||||
{
|
{
|
||||||
return _sys_call2 (SYS_fstat, (int)fd, (int)statbuf);
|
return _sys_call2 (SYS_fstat, (long)fd, (long)statbuf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,28 +27,23 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#define SYS_fork 0x02
|
|
||||||
#define SYS_read 0x03
|
|
||||||
#define SYS_open 0x05
|
|
||||||
#define SYS_waitpid 0x07
|
|
||||||
#define SYS_execve 0x0b
|
|
||||||
#define SYS_chmod 0x0f
|
|
||||||
#define SYS_access 0x21
|
|
||||||
#define SYS_brk 0x2d
|
|
||||||
#define SYS_ioctl 0x36
|
|
||||||
#define SYS_fsync 0x76
|
|
||||||
|
|
||||||
#if __MESC__
|
#if __MESC__
|
||||||
|
|
||||||
#include <linux/mes.c>
|
#include <linux/x86-mes/mes.c>
|
||||||
|
|
||||||
#else // !__MESC__
|
#elif __i386__
|
||||||
|
|
||||||
#include <assert.h>
|
#include <linux/x86-mes-gcc/mes.c>
|
||||||
|
|
||||||
#include <linux/gcc.c>
|
#elif __x86_64__
|
||||||
|
|
||||||
#endif // !__MESC__
|
#include <linux/x86_64-mes-gcc/mes.c>
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error arch not supported
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
fork ()
|
fork ()
|
||||||
|
@ -59,7 +54,20 @@ fork ()
|
||||||
ssize_t
|
ssize_t
|
||||||
read (int filedes, void *buffer, size_t size)
|
read (int filedes, void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
return _sys_call3 (SYS_read, (int)filedes, (int)buffer, (int)size);
|
ssize_t bytes = _sys_call3 (SYS_read, (long)filedes, (long)buffer, (long)size);
|
||||||
|
if (__mes_debug () > 3)
|
||||||
|
{
|
||||||
|
if (bytes == 1)
|
||||||
|
{
|
||||||
|
eputs ("read fd="); eputs (itoa ((int)filedes)); eputs (" c="); eputc (*(char*)buffer); eputs ("\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
eputs ("read fd="); eputs (itoa ((int)filedes));
|
||||||
|
eputs (" bytes="); eputs (itoa (bytes)); eputs ("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -75,7 +83,7 @@ open (char const *file_name, int flags, ...)
|
||||||
_ungetc_fd = -1;
|
_ungetc_fd = -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
int r = _sys_call3 (SYS_open, (int)file_name, (int)flags, (int)mask);
|
int r = _sys_call3 (SYS_open, (long)file_name, (long)flags, (long)mask);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -83,31 +91,37 @@ open (char const *file_name, int flags, ...)
|
||||||
pid_t
|
pid_t
|
||||||
waitpid (pid_t pid, int *status_ptr, int options)
|
waitpid (pid_t pid, int *status_ptr, int options)
|
||||||
{
|
{
|
||||||
return _sys_call3 (SYS_waitpid, (int)pid, (int)status_ptr, (int)options);
|
#if __i386__
|
||||||
|
return _sys_call3 (SYS_waitpid, (long)pid, (long)status_ptr, (long)options);
|
||||||
|
#elif __x86_64__
|
||||||
|
return _sys_call4 (SYS_wait4, (long)pid, (long)status_ptr, (long)options, 0);
|
||||||
|
#else
|
||||||
|
#error arch not supported
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
execve (char const* file_name, char *const argv[], char *const env[])
|
execve (char const* file_name, char *const argv[], char *const env[])
|
||||||
{
|
{
|
||||||
return _sys_call3 (SYS_execve, (int)file_name, (int)argv, (int)env);
|
return _sys_call3 (SYS_execve, (long)file_name, (long)argv, (long)env);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
chmod (char const *file_name, mode_t mask)
|
chmod (char const *file_name, mode_t mask)
|
||||||
{
|
{
|
||||||
return _sys_call2 (SYS_chmod, (int)file_name, (int)mask);
|
return _sys_call2 (SYS_chmod, (long)file_name, (long)mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
access (char const *file_name, int how)
|
access (char const *file_name, int how)
|
||||||
{
|
{
|
||||||
return _sys_call2 (SYS_access, (int)file_name, (int)how);
|
return _sys_call2 (SYS_access, (long)file_name, (long)how);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
long
|
||||||
brk (void *addr)
|
brk (void *addr)
|
||||||
{
|
{
|
||||||
return _sys_call1 (SYS_brk, (int)addr);
|
return _sys_call1 (SYS_brk, (long)addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -116,7 +130,7 @@ ioctl (int filedes, unsigned long command, ...)
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start (ap, command);
|
va_start (ap, command);
|
||||||
int data = va_arg (ap, int);
|
int data = va_arg (ap, int);
|
||||||
int r = _sys_call3 (SYS_ioctl, (int)filedes, (int)command, (int)data);
|
int r = _sys_call3 (SYS_ioctl, (long)filedes, (long)command, (long)data);
|
||||||
va_end (ap);
|
va_end (ap);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -124,5 +138,5 @@ ioctl (int filedes, unsigned long command, ...)
|
||||||
int
|
int
|
||||||
fsync (int filedes)
|
fsync (int filedes)
|
||||||
{
|
{
|
||||||
return _sys_call1 (SYS_fsync, (int)filedes);
|
return _sys_call1 (SYS_fsync, (long)filedes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,35 +33,35 @@ close (int filedes)
|
||||||
_ungetc_pos = -1;
|
_ungetc_pos = -1;
|
||||||
_ungetc_fd = -1;
|
_ungetc_fd = -1;
|
||||||
}
|
}
|
||||||
return _sys_call1 (SYS_close, (int)filedes);
|
return _sys_call1 (SYS_close, (long)filedes);
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t
|
off_t
|
||||||
lseek (int filedes, off_t offset, int whence)
|
lseek (int filedes, off_t offset, int whence)
|
||||||
{
|
{
|
||||||
return _sys_call3 (SYS_lseek, (int)filedes, (int)offset, (int)whence);
|
return _sys_call3 (SYS_lseek, (long)filedes, (long)offset, (long)whence);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
unlink (char const *file_name)
|
unlink (char const *file_name)
|
||||||
{
|
{
|
||||||
return _sys_call1 (SYS_unlink, (int)file_name);
|
return _sys_call1 (SYS_unlink, (long)file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
rmdir (char const *file_name)
|
rmdir (char const *file_name)
|
||||||
{
|
{
|
||||||
return _sys_call1 (SYS_rmdir, (int)file_name);
|
return _sys_call1 (SYS_rmdir, (long)file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
stat (char const *file_name, struct stat *statbuf)
|
stat (char const *file_name, struct stat *statbuf)
|
||||||
{
|
{
|
||||||
return _sys_call2 (SYS_stat, (int)file_name, (int)statbuf);
|
return _sys_call2 (SYS_stat, (long)file_name, (long)statbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
getcwd (char *buffer, size_t size)
|
getcwd (char *buffer, size_t size)
|
||||||
{
|
{
|
||||||
return _sys_call2 (SYS_getcwd, (int)buffer, (int)size);
|
return _sys_call2 (SYS_getcwd, (long)buffer, (long)size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,12 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <linux/x86/syscall.h>
|
||||||
|
|
||||||
int
|
long
|
||||||
_sys_call (int sys_call)
|
_sys_call (long sys_call)
|
||||||
{
|
{
|
||||||
int r;
|
long r;
|
||||||
asm (
|
asm (
|
||||||
"mov %1,%%eax\n\t"
|
"mov %1,%%eax\n\t"
|
||||||
"int $0x80\n\t"
|
"int $0x80\n\t"
|
||||||
|
@ -42,10 +43,10 @@ _sys_call (int sys_call)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
long
|
||||||
_sys_call1 (int sys_call, int one)
|
_sys_call1 (long sys_call, long one)
|
||||||
{
|
{
|
||||||
int r;
|
long r;
|
||||||
asm (
|
asm (
|
||||||
"mov %1,%%eax\n\t"
|
"mov %1,%%eax\n\t"
|
||||||
"mov %2,%%ebx\n\t"
|
"mov %2,%%ebx\n\t"
|
||||||
|
@ -65,10 +66,10 @@ _sys_call1 (int sys_call, int one)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
long
|
||||||
_sys_call2 (int sys_call, int one, int two)
|
_sys_call2 (long sys_call, long one, long two)
|
||||||
{
|
{
|
||||||
int r;
|
long r;
|
||||||
asm (
|
asm (
|
||||||
"mov %1,%%eax\n\t"
|
"mov %1,%%eax\n\t"
|
||||||
"mov %2,%%ebx\n\t"
|
"mov %2,%%ebx\n\t"
|
||||||
|
@ -89,10 +90,10 @@ _sys_call2 (int sys_call, int one, int two)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
long
|
||||||
_sys_call3 (int sys_call, int one, int two, int three)
|
_sys_call3 (long sys_call, long one, long two, long three)
|
||||||
{
|
{
|
||||||
int r;
|
long r;
|
||||||
asm (
|
asm (
|
||||||
"mov %2,%%ebx\n\t"
|
"mov %2,%%ebx\n\t"
|
||||||
"mov %3,%%ecx\n\t"
|
"mov %3,%%ecx\n\t"
|
||||||
|
@ -113,3 +114,29 @@ _sys_call3 (int sys_call, int one, int two, int three)
|
||||||
errno = 0;
|
errno = 0;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
_sys_call4 (long sys_call, long one, long two, long three, long four)
|
||||||
|
{
|
||||||
|
long r;
|
||||||
|
asm (
|
||||||
|
"mov %2,%%ebx\n\t"
|
||||||
|
"mov %3,%%ecx\n\t"
|
||||||
|
"mov %4,%%edx\n\t"
|
||||||
|
"mov %5,%%esi\n\t"
|
||||||
|
"mov %1,%%eax\n\t"
|
||||||
|
"int $0x80\n\t"
|
||||||
|
"mov %%eax,%0\n\t"
|
||||||
|
: "=r" (r)
|
||||||
|
: "rm" (sys_call), "rm" (one), "rm" (two), "rm" (three), "rm" (four)
|
||||||
|
: "eax", "ebx", "ecx", "edx", "esi"
|
||||||
|
);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
errno = -r;
|
||||||
|
r = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
errno = 0;
|
||||||
|
return r;
|
||||||
|
}
|
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <linux/x86/syscall.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
__sys_call (int sys_call)
|
__sys_call (int sys_call)
|
||||||
|
@ -54,6 +55,17 @@ __sys_call3 (int sys_call, int one, int two, int three)
|
||||||
asm ("int____$0x80");
|
asm ("int____$0x80");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
__sys_call4 (int sys_call, int one, int two, int three, int four)
|
||||||
|
{
|
||||||
|
asm ("mov____0x8(%ebp),%eax !8");
|
||||||
|
asm ("mov____0x8(%ebp),%ebx !12");
|
||||||
|
asm ("mov____0x8(%ebp),%ecx !16");
|
||||||
|
asm ("mov____0x8(%ebp),%edx !20");
|
||||||
|
asm ("mov____0x8(%ebp),%esi !24");
|
||||||
|
asm ("int____$0x80");
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
_sys_call (int sys_call)
|
_sys_call (int sys_call)
|
||||||
{
|
{
|
||||||
|
@ -109,3 +121,17 @@ _sys_call3 (int sys_call, int one, int two, int three)
|
||||||
errno = 0;
|
errno = 0;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
_sys_call4 (int sys_call, int one, int two, int three, int four)
|
||||||
|
{
|
||||||
|
int r = __sys_call4 (sys_call, one, two, three, four);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
errno = -r;
|
||||||
|
r = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
errno = 0;
|
||||||
|
return r;
|
||||||
|
}
|
149
lib/linux/x86_64-mes-gcc/mes.c
Normal file
149
lib/linux/x86_64-mes-gcc/mes.c
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
/* -*-comment-start: "//";comment-end:""-*-
|
||||||
|
* GNU Mes --- Maxwell Equations of Software
|
||||||
|
* Copyright © 2016,2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
|
||||||
|
*
|
||||||
|
* This file is part of GNU Mes.
|
||||||
|
*
|
||||||
|
* GNU 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.
|
||||||
|
*
|
||||||
|
* GNU 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 GNU Mes. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <linux/x86_64/syscall.h>
|
||||||
|
|
||||||
|
// HMM, merge this with x86-mes-gcc/mes.c, doing something like
|
||||||
|
// #define R0 eax
|
||||||
|
// #define R1 ebx
|
||||||
|
//
|
||||||
|
// #define R0 rax
|
||||||
|
// #define R1 rdi
|
||||||
|
|
||||||
|
long
|
||||||
|
_sys_call (long sys_call)
|
||||||
|
{
|
||||||
|
long r;
|
||||||
|
asm (
|
||||||
|
"mov %1,%%rax\n\t"
|
||||||
|
"syscall \n\t"
|
||||||
|
"mov %%rax,%0\n\t"
|
||||||
|
: "=r" (r)
|
||||||
|
: "rm" (sys_call)
|
||||||
|
: "rax"
|
||||||
|
);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
errno = -r;
|
||||||
|
r = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
errno = 0;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
_sys_call1 (long sys_call, long one)
|
||||||
|
{
|
||||||
|
long r;
|
||||||
|
asm (
|
||||||
|
"mov %1,%%rax\n\t"
|
||||||
|
"mov %2,%%rdi\n\t"
|
||||||
|
"syscall \n\t"
|
||||||
|
"mov %%rax,%0\n\t"
|
||||||
|
: "=r" (r)
|
||||||
|
: "rm" (sys_call), "rm" (one)
|
||||||
|
: "rax", "rdi"
|
||||||
|
);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
errno = -r;
|
||||||
|
r = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
errno = 0;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
_sys_call2 (long sys_call, long one, long two)
|
||||||
|
{
|
||||||
|
long r;
|
||||||
|
asm (
|
||||||
|
"mov %1,%%rax\n\t"
|
||||||
|
"mov %2,%%rdi\n\t"
|
||||||
|
"mov %3,%%rsi\n\t"
|
||||||
|
"syscall \n\t"
|
||||||
|
"mov %%rax,%0\n\t"
|
||||||
|
: "=r" (r)
|
||||||
|
: "rm" (sys_call), "rm" (one), "rm" (two)
|
||||||
|
: "rax", "rdi", "rsi"
|
||||||
|
);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
errno = -r;
|
||||||
|
r = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
errno = 0;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
_sys_call3 (long sys_call, long one, long two, long three)
|
||||||
|
{
|
||||||
|
long r;
|
||||||
|
asm (
|
||||||
|
"mov %2,%%rdi\n\t"
|
||||||
|
"mov %3,%%rsi\n\t"
|
||||||
|
"mov %4,%%rdx\n\t"
|
||||||
|
"mov %1,%%rax\n\t"
|
||||||
|
"syscall \n\t"
|
||||||
|
"mov %%rax,%0\n\t"
|
||||||
|
: "=r" (r)
|
||||||
|
: "rm" (sys_call), "rm" (one), "rm" (two), "rm" (three)
|
||||||
|
: "rax", "rdi", "rsi", "rdx"
|
||||||
|
);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
errno = -r;
|
||||||
|
r = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
errno = 0;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
_sys_call4 (long sys_call, long one, long two, long three, long four)
|
||||||
|
{
|
||||||
|
long r;
|
||||||
|
asm (
|
||||||
|
"mov %2,%%rdi\n\t"
|
||||||
|
"mov %3,%%rsi\n\t"
|
||||||
|
"mov %4,%%rdx\n\t"
|
||||||
|
"mov %5,%%rcx\n\t"
|
||||||
|
"mov %1,%%rax\n\t"
|
||||||
|
"syscall \n\t"
|
||||||
|
"mov %%rax,%0\n\t"
|
||||||
|
: "=r" (r)
|
||||||
|
: "rm" (sys_call), "rm" (one), "rm" (two), "rm" (three), "rm" (four)
|
||||||
|
: "rax", "rdi", "rsi", "rdx", "rcx"
|
||||||
|
);
|
||||||
|
if (r < 0)
|
||||||
|
{
|
||||||
|
errno = -r;
|
||||||
|
r = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
errno = 0;
|
||||||
|
return r;
|
||||||
|
}
|
|
@ -16,7 +16,6 @@
|
||||||
### You should have received a copy of the GNU General Public License
|
### You should have received a copy of the GNU General Public License
|
||||||
### along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
|
### along with GNU Mes. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
DEFINE add____$i32,%eax 05
|
DEFINE add____$i32,%eax 05
|
||||||
DEFINE add____$i32,%ecx 81c1
|
DEFINE add____$i32,%ecx 81c1
|
||||||
DEFINE add____$i32,%edx 81c2
|
DEFINE add____$i32,%edx 81c2
|
||||||
|
@ -140,6 +139,7 @@ DEFINE mov____0x8(%ebp),%ebp 8b6d
|
||||||
DEFINE mov____0x8(%ebp),%ebx 8b5d
|
DEFINE mov____0x8(%ebp),%ebx 8b5d
|
||||||
DEFINE mov____0x8(%ebp),%ecx 8b4d
|
DEFINE mov____0x8(%ebp),%ecx 8b4d
|
||||||
DEFINE mov____0x8(%ebp),%edx 8b55
|
DEFINE mov____0x8(%ebp),%edx 8b55
|
||||||
|
DEFINE mov____0x8(%ebp),%esi 8b75
|
||||||
DEFINE mov____0x8(%ebp),%esp 8b65
|
DEFINE mov____0x8(%ebp),%esp 8b65
|
||||||
DEFINE movsbl_%al,%eax 0fbec0
|
DEFINE movsbl_%al,%eax 0fbec0
|
||||||
DEFINE movswl_%ax,%eax 0fbfc0
|
DEFINE movswl_%ax,%eax 0fbfc0
|
||||||
|
@ -204,16 +204,6 @@ DEFINE xor____%ecx,%ecx 31c9
|
||||||
DEFINE xor____%edx,%eax 31d0
|
DEFINE xor____%edx,%eax 31d0
|
||||||
DEFINE xor____%edx,%edx 31d2
|
DEFINE xor____%edx,%edx 31d2
|
||||||
|
|
||||||
# Deprecated. Remove after 0.14 release.
|
|
||||||
DEFINE mov____%al,0x32(%ebp) 8885
|
|
||||||
DEFINE mov____%al,0x8(%ebp) 8845
|
|
||||||
DEFINE mov____%ax,0x32(%ebp) 668985
|
|
||||||
DEFINE mov____%ax,0x8(%ebp) 668945
|
|
||||||
DEFINE movzbl_0x32(%ebp),%eax 0fb685
|
|
||||||
DEFINE movzbl_0x8(%ebp),%edx 0fb655
|
|
||||||
DEFINE movzwl_0x8(%ebp),%eax 0fb745
|
|
||||||
DEFINE movzwl_0x8(%ebp),%eax 0fb745
|
|
||||||
|
|
||||||
DEFINE SYS_exit 01000000
|
DEFINE SYS_exit 01000000
|
||||||
DEFINE SYS_fork 02000000
|
DEFINE SYS_fork 02000000
|
||||||
DEFINE SYS_read 03000000
|
DEFINE SYS_read 03000000
|
||||||
|
|
6
src/gc.c
6
src/gc.c
|
@ -73,7 +73,7 @@ gc_copy (SCM old) ///((internal))
|
||||||
if (NTYPE (new) == TVECTOR)
|
if (NTYPE (new) == TVECTOR)
|
||||||
{
|
{
|
||||||
NVECTOR (new) = g_free;
|
NVECTOR (new) = g_free;
|
||||||
for (int i=0; i<LENGTH (old); i++)
|
for (long i=0; i<LENGTH (old); i++)
|
||||||
g_news[g_free++] = g_cells[VECTOR (old)+i];
|
g_news[g_free++] = g_cells[VECTOR (old)+i];
|
||||||
}
|
}
|
||||||
TYPE (old) = TBROKEN_HEART;
|
TYPE (old) = TBROKEN_HEART;
|
||||||
|
@ -172,7 +172,7 @@ gc_ () ///((internal))
|
||||||
g_free = 1;
|
g_free = 1;
|
||||||
|
|
||||||
#if __MESC__
|
#if __MESC__
|
||||||
if (ARENA_SIZE < MAX_ARENA_SIZE && (int)g_news > 0)
|
if (ARENA_SIZE < MAX_ARENA_SIZE && (long)g_news > 0)
|
||||||
#else
|
#else
|
||||||
if (ARENA_SIZE < MAX_ARENA_SIZE && g_news > 0)
|
if (ARENA_SIZE < MAX_ARENA_SIZE && g_news > 0)
|
||||||
#endif
|
#endif
|
||||||
|
@ -194,7 +194,7 @@ gc_ () ///((internal))
|
||||||
gc_up_arena ();
|
gc_up_arena ();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=g_free; i<g_symbol_max; i++)
|
for (long i=g_free; i<g_symbol_max; i++)
|
||||||
gc_copy (i);
|
gc_copy (i);
|
||||||
g_symbols = gc_copy (g_symbols);
|
g_symbols = gc_copy (g_symbols);
|
||||||
g_macros = gc_copy (g_macros);
|
g_macros = gc_copy (g_macros);
|
||||||
|
|
40
src/mes.c
40
src/mes.c
|
@ -26,14 +26,14 @@
|
||||||
|
|
||||||
//#define MES_MINI 1
|
//#define MES_MINI 1
|
||||||
#if POSIX
|
#if POSIX
|
||||||
int ARENA_SIZE = 100000000; // 64b: 4GiB
|
long ARENA_SIZE = 100000000; // 64b: 4GiB
|
||||||
#else
|
#else
|
||||||
int ARENA_SIZE = 200000; // 32b: 2MiB, 64b: 4 MiB
|
long ARENA_SIZE = 200000; // 32b: 2MiB, 64b: 4 MiB
|
||||||
#endif
|
#endif
|
||||||
int MAX_ARENA_SIZE = 100000000;
|
long MAX_ARENA_SIZE = 100000000;
|
||||||
|
|
||||||
int JAM_SIZE = 20000;
|
long JAM_SIZE = 20000;
|
||||||
int GC_SAFETY = 2000;
|
long GC_SAFETY = 2000;
|
||||||
|
|
||||||
char *g_arena = 0;
|
char *g_arena = 0;
|
||||||
typedef long SCM;
|
typedef long SCM;
|
||||||
|
@ -66,8 +66,8 @@ struct scm {
|
||||||
SCM cdr;
|
SCM cdr;
|
||||||
};
|
};
|
||||||
struct function {
|
struct function {
|
||||||
int (*function) (void);
|
long (*function) (void);
|
||||||
int arity;
|
long arity;
|
||||||
char *name;
|
char *name;
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
|
@ -84,7 +84,7 @@ struct function {
|
||||||
function3_t function3;
|
function3_t function3;
|
||||||
functionn_t functionn;
|
functionn_t functionn;
|
||||||
};
|
};
|
||||||
int arity;
|
long arity;
|
||||||
char const *name;
|
char const *name;
|
||||||
};
|
};
|
||||||
struct scm {
|
struct scm {
|
||||||
|
@ -95,12 +95,12 @@ struct scm {
|
||||||
SCM ref;
|
SCM ref;
|
||||||
SCM string;
|
SCM string;
|
||||||
SCM variable;
|
SCM variable;
|
||||||
int length;
|
long length;
|
||||||
};
|
};
|
||||||
union {
|
union {
|
||||||
int value;
|
long value;
|
||||||
int function;
|
long function;
|
||||||
int port;
|
long port;
|
||||||
SCM cdr;
|
SCM cdr;
|
||||||
SCM closure;
|
SCM closure;
|
||||||
SCM continuation;
|
SCM continuation;
|
||||||
|
@ -337,7 +337,7 @@ int g_function = 0;
|
||||||
#define CDADAR(x) CAR (CDR (CAR (CDR (x))))
|
#define CDADAR(x) CAR (CDR (CAR (CDR (x))))
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
alloc (int n)
|
alloc (long n)
|
||||||
{
|
{
|
||||||
SCM x = g_free;
|
SCM x = g_free;
|
||||||
g_free += n;
|
g_free += n;
|
||||||
|
@ -345,7 +345,7 @@ alloc (int n)
|
||||||
}
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
make_cell__ (int type, SCM car, SCM cdr)
|
make_cell__ (long type, SCM car, SCM cdr)
|
||||||
{
|
{
|
||||||
SCM x = alloc (1);
|
SCM x = alloc (1);
|
||||||
TYPE (x) = type;
|
TYPE (x) = type;
|
||||||
|
@ -358,7 +358,7 @@ SCM
|
||||||
make_cell_ (SCM type, SCM car, SCM cdr)
|
make_cell_ (SCM type, SCM car, SCM cdr)
|
||||||
{
|
{
|
||||||
assert (TYPE (type) == TNUMBER);
|
assert (TYPE (type) == TNUMBER);
|
||||||
int t = VALUE (type);
|
long t = VALUE (type);
|
||||||
if (t == TCHAR || t == TNUMBER)
|
if (t == TCHAR || t == TNUMBER)
|
||||||
return make_cell__ (t, car ? CAR (car) : 0, cdr ? CDR (cdr) : 0);
|
return make_cell__ (t, car ? CAR (car) : 0, cdr ? CDR (cdr) : 0);
|
||||||
return make_cell__ (t, car, cdr);
|
return make_cell__ (t, car, cdr);
|
||||||
|
@ -503,10 +503,10 @@ acons (SCM key, SCM value, SCM alist)
|
||||||
return cons (cons (key, value), alist);
|
return cons (cons (key, value), alist);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
long
|
||||||
length__ (SCM x) ///((internal))
|
length__ (SCM x) ///((internal))
|
||||||
{
|
{
|
||||||
int n = 0;
|
long n = 0;
|
||||||
while (x != cell_nil)
|
while (x != cell_nil)
|
||||||
{
|
{
|
||||||
n++;
|
n++;
|
||||||
|
@ -541,7 +541,7 @@ error (SCM key, SCM x)
|
||||||
}
|
}
|
||||||
|
|
||||||
SCM
|
SCM
|
||||||
string_to_list (char const* s, int i)
|
string_to_list (char const* s, long i)
|
||||||
{
|
{
|
||||||
SCM p = cell_nil;
|
SCM p = cell_nil;
|
||||||
while (i--)
|
while (i--)
|
||||||
|
@ -567,8 +567,8 @@ assert_defined (SCM x, SCM e) ///((internal))
|
||||||
SCM
|
SCM
|
||||||
check_formals (SCM f, SCM formals, SCM args) ///((internal))
|
check_formals (SCM f, SCM formals, SCM args) ///((internal))
|
||||||
{
|
{
|
||||||
int flen = (TYPE (formals) == TNUMBER) ? VALUE (formals) : length__ (formals);
|
long flen = (TYPE (formals) == TNUMBER) ? VALUE (formals) : length__ (formals);
|
||||||
int alen = length__ (args);
|
long alen = length__ (args);
|
||||||
if (alen != flen && alen != -1 && flen != -1)
|
if (alen != flen && alen != -1 && flen != -1)
|
||||||
{
|
{
|
||||||
char *s = "apply: wrong number of arguments; expected: ";
|
char *s = "apply: wrong number of arguments; expected: ";
|
||||||
|
|
Loading…
Reference in a new issue