1 |
/* dalloca.h - alloca function for tinycc which doesn't have one natively |
2 |
* $Id$ |
3 |
*/ |
4 |
|
5 |
/* |
6 |
* Copyright (C) 2003 Damian M Gryski <dgryski@uwaterloo.ca> |
7 |
* Released under LGPL 2.1 |
8 |
*/ |
9 |
|
10 |
#ifdef __TINYC__ |
11 |
|
12 |
#ifdef NO_ALLOCA_CHECK |
13 |
#define alloca_assert(expr) |
14 |
#else |
15 |
#include <assert.h> |
16 |
#define alloca_assert(expr) assert(expr) |
17 |
#endif |
18 |
|
19 |
/* |
20 |
* `size' is known at compile time, but tccasm doesn't like the math expr. |
21 |
* Blindly accept input, but at least assert() that it's good. |
22 |
* Since the assert() check is substantially more expensive than the alloca |
23 |
* itself, the check can be turned off by compiling with -DNO_ALLOCA_CHECK |
24 |
*/ |
25 |
|
26 |
#define alloca_const(size) \ |
27 |
({ void * __sp; \ |
28 |
alloca_assert(size % 4 == 0); \ |
29 |
asm("subl $" #size ", %%esp\n" \ |
30 |
"movl %%esp, %0" \ |
31 |
: "=m" (__sp) ) ; \ |
32 |
__sp; }) |
33 |
|
34 |
#define alloca_var(size) \ |
35 |
({ void * __sp; unsigned int __arg = size; \ |
36 |
asm("movl %1, %%eax\n" /* get the size */ \ |
37 |
"addl $3, %%eax\n" /* eax := (eax + 3) & -4 */ \ |
38 |
"andl $-4, %%eax\n" /* rounds to next multiple of 4 */ \ |
39 |
"subl %%eax, %%esp\n" /* adjust stack pointer */ \ |
40 |
"movl %%esp, %0\n" /* return result */ \ |
41 |
: "=m" (__sp) : "m" (__arg) : "eax") ; \ |
42 |
__sp ; }) |
43 |
|
44 |
|
45 |
#define alloca(size) alloca_var(size) |
46 |
|
47 |
#endif |