562079b6835ba14f35dc28af9ab3b411bc845430
[mes.git] / mlibc.c
1 /* -*-comment-start: "//";comment-end:""-*-
2  * Mes --- Maxwell Equations of Software
3  * Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
4  *
5  * This file is part of Mes.
6  *
7  * Mes is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or (at
10  * your option) any later version.
11  *
12  * Mes is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #if __GNUC__
22 int g_stdin = 0;
23 typedef long size_t;
24 void *malloc (size_t i);
25 int open (char const *s, int mode);
26 int read (int fd, void* buf, size_t n);
27 void write (int fd, char const* s, int n);
28
29 #define O_RDONLY 0
30 #define INT_MIN -2147483648
31 #define INT_MAX 2147483647
32 #define EOF -1
33 #define STDIN 0
34 #define STDOUT 1
35 #define STDERR 2
36
37 void
38 exit (int code)
39 {
40   asm (
41        "movl %0,%%ebx\n\t"
42        "movl $1,%%eax\n\t"
43        "int  $0x80"
44        : // no outputs "=" (r)
45        : "" (code)
46        );
47   // not reached
48   exit (0);
49 }
50
51 char const*
52 getenv (char const* p)
53 {
54   return 0;
55 }
56
57 int
58 read (int fd, void* buf, size_t n)
59 {
60   int r;
61   //syscall (SYS_write, fd, s, n));
62   asm (
63        "movl %1,%%ebx\n\t"
64        "movl %2,%%ecx\n\t"
65        "movl %3,%%edx\n\t"
66
67        "movl $0x3,%%eax\n\t"
68        "int  $0x80\n\t"
69
70        "mov %%eax,%0\n\t"
71        : "=r" (r)
72        : "" (fd), "" (buf), "" (n)
73        : "eax", "ebx", "ecx", "edx"
74        );
75   return r;
76 }
77
78 int
79 open (char const *s, int mode)
80 {
81   int r;
82   //syscall (SYS_open, mode));
83   asm (
84        "mov %1,%%ebx\n\t"
85        "mov %2,%%ecx\n\t"
86        "mov $0x5,%%eax\n\t"
87        "int $0x80\n\t"
88        "mov %%eax,%0\n\t"
89        : "=r" (r)
90        : "" (s), "" (mode)
91        : "eax", "ebx", "ecx"
92        );
93   return r;
94 }
95
96 int puts (char const*);
97 char const* itoa (int);
98
99 void
100 write (int fd, char const* s, int n)
101 {
102   int r;
103   //syscall (SYS_write, fd, s, n));
104   asm (
105        "mov %0,%%ebx\n\t"
106        "mov %1,%%ecx\n\t"
107        "mov %2,%%edx\n\t"
108
109        "mov $0x4, %%eax\n\t"
110        "int $0x80\n\t"
111        : // no outputs "=" (r)
112        : "" (fd), "" (s), "" (n)
113        : "eax", "ebx", "ecx", "edx"
114        );
115 }
116
117 void *
118 brk (void *p)
119 {
120   void *r;
121   asm (
122        "mov %1,%%ebx\n\t"
123
124        "mov $0x2d,%%eax\n\t"
125        "int $0x80\n\t"
126
127        "mov %%eax,%0\n\t"
128        : "=r" (r)
129        : "" (p)
130        : "eax", "ebx"
131        );
132   return r;
133 }
134
135 int
136 putc (int c, int fd)
137 {
138   write (fd, (char*)&c, 1);
139   return 0;
140 }
141
142 int
143 putchar (int c)
144 {
145   write (STDOUT, (char*)&c, 1);
146   return 0;
147 }
148
149 void *g_malloc_base = 0;
150
151 void *
152 malloc (size_t size)
153 {
154   void *p = brk (0);
155   if (!g_malloc_base) g_malloc_base = p;
156   brk (p+size);
157   return p;
158 }
159
160 void *
161 realloc (void *p, size_t size)
162 {
163   (void)p;
164   brk (g_malloc_base + size);
165   return g_malloc_base;
166 }
167
168 void
169 free (void *p)
170 {
171   int *n = (int*)p-1;
172   //munmap ((void*)p, *n);
173 }
174
175 size_t
176 strlen (char const* s)
177 {
178   int i = 0;
179   while (s[i]) i++;
180   return i;
181 }
182
183 int
184 strcmp (char const* a, char const* b)
185 {
186   while (*a && *b && *a == *b) {a++;b++;}
187   return *a - *b;
188 }
189
190 int
191 eputs (char const* s)
192 {
193   int i = strlen (s);
194   write (STDERR, s, i);
195   return 0;
196 }
197
198 int
199 fputs (char const* s, int fd)
200 {
201   int i = strlen (s);
202   write (fd, s, i);
203   return 0;
204 }
205
206 int
207 puts (char const* s)
208 {
209   int i = strlen (s);
210   write (STDOUT, s, i);
211   return 0;
212 }
213
214 void
215 assert_fail (char* s)
216 {
217   eputs ("assert fail: ");
218   eputs (s);
219   eputs ("\n");
220   *((int*)0) = 0;
221 }
222
223 #define assert(x) ((x) ? (void)0 : assert_fail (#x))
224
225
226 int ungetc_char = -1;
227 char ungetc_buf[2];
228
229 int
230 getchar ()
231 {
232   char c;
233   int i;
234   if (ungetc_char == -1)
235     {
236       int r = read (g_stdin, &c, 1);
237       if (r < 1) return -1;
238       i = c;
239     }
240   else
241     i = ungetc_buf[ungetc_char--];
242
243   if (i < 0) i += 256;
244
245   return i;
246 }
247
248 int
249 ungetc (int c, int fd)
250 {
251   assert (ungetc_char < 2);
252   ungetc_buf[++ungetc_char] = c;
253   return c;
254 }
255
256 char itoa_buf[10];
257
258 char const*
259 itoa (int x)
260 {
261   //static char itoa_buf[10];
262   //char *p = buf+9;
263   char *p = itoa_buf;
264   p += 9;
265   *p-- = 0;
266
267   //int sign = x < 0;
268   int sign;
269   sign = x < 0;
270   if (sign)
271     x = -x;
272
273   do
274     {
275       *p-- = '0' + (x % 10);
276       x = x / 10;
277     } while (x);
278
279   if (sign)
280     *p-- = '-';
281
282   return p+1;
283 }
284
285 int
286 isdigit (int c)
287 {
288   return (c>='0') && (c<='9');
289 }
290 #endif