Subversion Repositories Kolibri OS

Rev

Rev 647 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 647 Rev 6429
Line 16... Line 16...
16
 * You should have received a copy of the GNU Lesser General Public
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
19
 */
Line -... Line 20...
-
 
20
 
-
 
21
#ifdef TARGET_DEFS_ONLY
20
 
22
 
21
/* number of available registers */
23
/* number of available registers */
-
 
24
#define NB_REGS         4
Line 22... Line 25...
22
#define NB_REGS             4
25
#define NB_ASM_REGS     8
23
 
26
 
24
/* a register can belong to several classes. The classes must be
27
/* a register can belong to several classes. The classes must be
25
   sorted from more general to more precise (see gv2() code which does
28
   sorted from more general to more precise (see gv2() code which does
Line 38... Line 41...
38
enum {
41
enum {
39
    TREG_EAX = 0,
42
    TREG_EAX = 0,
40
    TREG_ECX,
43
    TREG_ECX,
41
    TREG_EDX,
44
    TREG_EDX,
42
    TREG_ST0,
45
    TREG_ST0,
43
};
-
 
44
 
-
 
45
int reg_classes[NB_REGS] = {
46
    TREG_ESP = 4
46
    /* eax */ RC_INT | RC_EAX,
-
 
47
    /* ecx */ RC_INT | RC_ECX,
-
 
48
    /* edx */ RC_INT | RC_EDX,
-
 
49
    /* st0 */ RC_FLOAT | RC_ST0,
-
 
50
};
47
};
Line 51... Line 48...
51
 
48
 
52
/* return registers for function */
49
/* return registers for function */
53
#define REG_IRET TREG_EAX /* single word int return register */
50
#define REG_IRET TREG_EAX /* single word int return register */
Line 57... Line 54...
57
/* defined if function parameters must be evaluated in reverse order */
54
/* defined if function parameters must be evaluated in reverse order */
58
#define INVERT_FUNC_PARAMS
55
#define INVERT_FUNC_PARAMS
Line 59... Line 56...
59
 
56
 
60
/* defined if structures are passed as pointers. Otherwise structures
57
/* defined if structures are passed as pointers. Otherwise structures
61
   are directly pushed on stack. */
58
   are directly pushed on stack. */
Line 62... Line 59...
62
//#define FUNC_STRUCT_PARAM_AS_PTR
59
/* #define FUNC_STRUCT_PARAM_AS_PTR */
63
 
60
 
Line 64... Line 61...
64
/* pointer size, in bytes */
61
/* pointer size, in bytes */
65
#define PTR_SIZE 4
62
#define PTR_SIZE 4
66
 
63
 
67
/* long double size and alignment, in bytes */
64
/* long double size and alignment, in bytes */
68
#define LDOUBLE_SIZE  12
65
#define LDOUBLE_SIZE  12
Line -... Line 66...
-
 
66
#define LDOUBLE_ALIGN 4
-
 
67
/* maximum alignment (for aligned attribute support) */
-
 
68
#define MAX_ALIGN     8
69
#define LDOUBLE_ALIGN 4
69
 
70
/* maximum alignment (for aligned attribute support) */
70
 
Line 71... Line 71...
71
#define MAX_ALIGN     8
71
#define psym oad
Line 72... Line 72...
72
 
72
 
73
/******************************************************/
73
/******************************************************/
-
 
74
/* ELF defines */
74
/* ELF defines */
75
 
75
 
76
#define EM_TCC_TARGET EM_386
Line 76... Line 77...
76
#define EM_TCC_TARGET EM_386
77
 
77
 
78
/* relocation type for 32 bit data relocation */
Line 78... Line 79...
78
/* relocation type for 32 bit data relocation */
79
#define R_DATA_32   R_386_32
-
 
80
#define R_DATA_PTR  R_386_32
-
 
81
#define R_JMP_SLOT  R_386_JMP_SLOT
-
 
82
#define R_COPY      R_386_COPY
-
 
83
 
-
 
84
#define ELF_START_ADDR 0x08048000
-
 
85
#define ELF_PAGE_SIZE  0x1000
-
 
86
 
-
 
87
/******************************************************/
-
 
88
#else /* ! TARGET_DEFS_ONLY */
-
 
89
/******************************************************/
Line 79... Line 90...
79
#define R_DATA_32   R_386_32
90
#include "tcc.h"
80
#define R_JMP_SLOT  R_386_JMP_SLOT
-
 
81
#define R_COPY      R_386_COPY
91
 
-
 
92
ST_DATA const int reg_classes[NB_REGS] = {
-
 
93
    /* eax */ RC_INT | RC_EAX,
-
 
94
    /* ecx */ RC_INT | RC_ECX,
Line 82... Line 95...
82
 
95
    /* edx */ RC_INT | RC_EDX,
83
#define ELF_START_ADDR 0x08048000
96
    /* st0 */ RC_FLOAT | RC_ST0,
84
#define ELF_PAGE_SIZE  0x1000
97
};
85
 
98
 
86
/******************************************************/
99
static unsigned long func_sub_sp_offset;
87
 
100
static int func_ret_sub;
88
static unsigned long func_sub_sp_offset;
101
#ifdef CONFIG_TCC_BCHECK
89
static unsigned long func_bound_offset;
102
static addr_t func_bound_offset;
90
static int func_ret_sub;
103
#endif
91
 
104
 
Line 92... Line 105...
92
/* XXX: make it faster ? */
105
/* XXX: make it faster ? */
93
void g(int c)
106
ST_FUNC void g(int c)
94
{
107
{
95
    int ind1;
108
    int ind1;
96
    ind1 = ind + 1;
109
    ind1 = ind + 1;
97
    if (ind1 > cur_text_section->data_allocated)
110
    if (ind1 > cur_text_section->data_allocated)
98
        section_realloc(cur_text_section, ind1);
111
        section_realloc(cur_text_section, ind1);
Line -... Line 112...
-
 
112
    cur_text_section->data[ind] = c;
-
 
113
    ind = ind1;
-
 
114
}
-
 
115
 
-
 
116
ST_FUNC void o(unsigned int c)
-
 
117
{
99
    cur_text_section->data[ind] = c;
118
    while (c) {
100
    ind = ind1;
119
        g(c);
101
}
120
        c = c >> 8;
102
 
121
    }
103
void o(unsigned int c)
122
}
104
{
123
 
105
    while (c) {
124
ST_FUNC void gen_le16(int v)
Line 106... Line 125...
106
        g(c);
125
{
107
        c = c >> 8;
126
    g(v);
108
    }
127
    g(v >> 8);
109
}
-
 
110
 
128
}
111
void gen_le32(int c)
129
 
112
{
130
ST_FUNC void gen_le32(int c)
113
    g(c);
131
{
114
    g(c >> 8);
132
    g(c);
115
    g(c >> 16);
133
    g(c >> 8);
116
    g(c >> 24);
134
    g(c >> 16);
Line 117... Line 135...
117
}
135
    g(c >> 24);
118
 
136
}
119
/* output a symbol and patch all calls to it */
137
 
120
void gsym_addr(int t, int a)
138
/* output a symbol and patch all calls to it */
Line 121... Line 139...
121
{
139
ST_FUNC void gsym_addr(int t, int a)
122
    int n, *ptr;
140
{
123
    while (t) {
141
    while (t) {
Line 124... Line 142...
124
        ptr = (int *)(cur_text_section->data + t);
142
        unsigned char *ptr = cur_text_section->data + t;
125
        n = *ptr; /* next value */
143
        uint32_t n = read32le(ptr); /* next value */
126
        *ptr = a - t - 4;
144
        write32le(ptr, a - t - 4);
127
        t = n;
145
        t = n;
Line 128... Line 146...
128
    }
146
    }
129
}
147
}
130
 
148
 
131
void gsym(int t)
149
ST_FUNC void gsym(int t)
132
{
150
{
133
    gsym_addr(t, ind);
151
    gsym_addr(t, ind);
134
}
152
}
135
 
153
 
136
/* psym is used to put an instruction with a data field which is a
154
/* psym is used to put an instruction with a data field which is a
Line 137... Line 155...
137
   reference to a symbol. It is in fact the same as oad ! */
155
   reference to a symbol. It is in fact the same as oad ! */
138
#define psym oad
156
#define psym oad
139
 
157
 
140
/* instruction + 4 bytes data. Return the address of the data */
158
/* instruction + 4 bytes data. Return the address of the data */
141
static int oad(int c, int s)
159
ST_FUNC int oad(int c, int s)
142
{
160
{
143
    int ind1;
161
    int ind1;
Line -... Line 162...
-
 
162
 
-
 
163
    o(c);
-
 
164
    ind1 = ind + 4;
-
 
165
    if (ind1 > cur_text_section->data_allocated)
-
 
166
        section_realloc(cur_text_section, ind1);
-
 
167
    write32le(cur_text_section->data + ind, s);
-
 
168
    s = ind;
144
 
169
    ind = ind1;
145
    o(c);
170
    return s;
146
    ind1 = ind + 4;
171
}
147
    if (ind1 > cur_text_section->data_allocated)
172
 
148
        section_realloc(cur_text_section, ind1);
173
/* output constant with relocation if 'r & VT_SYM' is true */
Line 181... Line 206...
181
    } else {
206
    } else {
182
        g(0x00 | op_reg | (r & VT_VALMASK));
207
        g(0x00 | op_reg | (r & VT_VALMASK));
183
    }
208
    }
184
}
209
}
Line 185... Line -...
185
 
-
 
186
 
210
 
187
/* load 'r' from value 'sv' */
211
/* load 'r' from value 'sv' */
188
void load(int r, SValue *sv)
212
ST_FUNC void load(int r, SValue *sv)
189
{
213
{
190
    int v, t, ft, fc, fr;
214
    int v, t, ft, fc, fr;
Line -... Line 215...
-
 
215
    SValue v1;
-
 
216
 
-
 
217
#ifdef TCC_TARGET_PE
-
 
218
    SValue v2;
-
 
219
    sv = pe_getimport(sv, &v2);
191
    SValue v1;
220
#endif
192
 
221
 
193
    fr = sv->r;
222
    fr = sv->r;
-
 
223
    ft = sv->type.t;
-
 
224
    fc = sv->c.i;
Line 194... Line 225...
194
    ft = sv->type.t;
225
 
195
    fc = sv->c.ul;
226
    ft &= ~(VT_VOLATILE | VT_CONSTANT);
196
 
227
 
197
    v = fr & VT_VALMASK;
228
    v = fr & VT_VALMASK;
198
    if (fr & VT_LVAL) {
229
    if (fr & VT_LVAL) {
199
        if (v == VT_LLOCAL) {
230
        if (v == VT_LLOCAL) {
200
            v1.type.t = VT_INT;
-
 
201
            v1.r = VT_LOCAL | VT_LVAL;
231
            v1.type.t = VT_INT;
-
 
232
            v1.r = VT_LOCAL | VT_LVAL;
-
 
233
            v1.c.i = fc;
-
 
234
            fr = r;
202
            v1.c.ul = fc;
235
            if (!(reg_classes[fr] & RC_INT))
203
            load(r, &v1);
236
                fr = get_reg(RC_INT);
204
            fr = r;
237
            load(fr, &v1);
205
        }
238
        }
206
        if ((ft & VT_BTYPE) == VT_FLOAT) {
239
        if ((ft & VT_BTYPE) == VT_FLOAT) {
207
            o(0xd9); /* flds */
240
            o(0xd9); /* flds */
208
            r = 0;
241
            r = 0;
209
        } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
242
        } else if ((ft & VT_BTYPE) == VT_DOUBLE) {
210
            o(0xdd); /* fldl */
243
            o(0xdd); /* fldl */
211
            r = 0;
244
            r = 0;
212
        } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
245
        } else if ((ft & VT_BTYPE) == VT_LDOUBLE) {
213
            o(0xdb); /* fldt */
246
            o(0xdb); /* fldt */
214
            r = 5;
247
            r = 5;
215
        } else if ((ft & VT_TYPE) == VT_BYTE) {
248
        } else if ((ft & VT_TYPE) == VT_BYTE || (ft & VT_TYPE) == VT_BOOL) {
216
            o(0xbe0f);   /* movsbl */
249
            o(0xbe0f);   /* movsbl */
217
        } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
250
        } else if ((ft & VT_TYPE) == (VT_BYTE | VT_UNSIGNED)) {
Line 227... Line 260...
227
    } else {
260
    } else {
228
        if (v == VT_CONST) {
261
        if (v == VT_CONST) {
229
            o(0xb8 + r); /* mov $xx, r */
262
            o(0xb8 + r); /* mov $xx, r */
230
            gen_addr32(fr, sv->sym, fc);
263
            gen_addr32(fr, sv->sym, fc);
231
        } else if (v == VT_LOCAL) {
264
        } else if (v == VT_LOCAL) {
-
 
265
            if (fc) {
232
            o(0x8d); /* lea xxx(%ebp), r */
266
                o(0x8d); /* lea xxx(%ebp), r */
233
            gen_modrm(r, VT_LOCAL, sv->sym, fc);
267
                gen_modrm(r, VT_LOCAL, sv->sym, fc);
-
 
268
            } else {
-
 
269
                o(0x89);
-
 
270
                o(0xe8 + r); /* mov %ebp, r */
-
 
271
            }
234
        } else if (v == VT_CMP) {
272
        } else if (v == VT_CMP) {
235
            oad(0xb8 + r, 0); /* mov $0, r */
273
            oad(0xb8 + r, 0); /* mov $0, r */
236
            o(0x0f); /* setxx %br */
274
            o(0x0f); /* setxx %br */
237
            o(fc);
275
            o(fc);
238
            o(0xc0 + r);
276
            o(0xc0 + r);
Line 248... Line 286...
248
        }
286
        }
249
    }
287
    }
250
}
288
}
Line 251... Line 289...
251
 
289
 
252
/* store register 'r' in lvalue 'v' */
290
/* store register 'r' in lvalue 'v' */
253
void store(int r, SValue *v)
291
ST_FUNC void store(int r, SValue *v)
254
{
292
{
Line -... Line 293...
-
 
293
    int fr, bt, ft, fc;
-
 
294
 
-
 
295
#ifdef TCC_TARGET_PE
-
 
296
    SValue v2;
-
 
297
    v = pe_getimport(v, &v2);
255
    int fr, bt, ft, fc;
298
#endif
256
 
299
 
257
    ft = v->type.t;
300
    ft = v->type.t;
-
 
301
    fc = v->c.i;
258
    fc = v->c.ul;
302
    fr = v->r & VT_VALMASK;
259
    fr = v->r & VT_VALMASK;
303
    ft &= ~(VT_VOLATILE | VT_CONSTANT);
260
    bt = ft & VT_BTYPE;
304
    bt = ft & VT_BTYPE;
261
    /* XXX: incorrect if float reg to reg */
305
    /* XXX: incorrect if float reg to reg */
262
    if (bt == VT_FLOAT) {
306
    if (bt == VT_FLOAT) {
Line 294... Line 338...
294
    } else {
338
    } else {
295
        oad(0xc481, val); /* add $xxx, %esp */
339
        oad(0xc481, val); /* add $xxx, %esp */
296
    }
340
    }
297
}
341
}
Line -... Line 342...
-
 
342
 
-
 
343
static void gen_static_call(int v)
-
 
344
{
-
 
345
    Sym *sym;
-
 
346
 
-
 
347
    sym = external_global_sym(v, &func_old_type, 0);
-
 
348
    oad(0xe8, -4);
-
 
349
    greloc(cur_text_section, sym, ind-4, R_386_PC32);
-
 
350
}
298
 
351
 
299
/* 'is_jmp' is '1' if it is a jump */
352
/* 'is_jmp' is '1' if it is a jump */
300
static void gcall_or_jmp(int is_jmp)
353
static void gcall_or_jmp(int is_jmp)
301
{
354
{
302
    int r;
355
    int r;
Line 309... Line 362...
309
        } else {
362
        } else {
310
            /* put an empty PC32 relocation */
363
            /* put an empty PC32 relocation */
311
            put_elf_reloc(symtab_section, cur_text_section, 
364
            put_elf_reloc(symtab_section, cur_text_section, 
312
                          ind + 1, R_386_PC32, 0);
365
                          ind + 1, R_386_PC32, 0);
313
        }
366
        }
314
        oad(0xe8 + is_jmp, vtop->c.ul - 4); /* call/jmp im */
367
        oad(0xe8 + is_jmp, vtop->c.i - 4); /* call/jmp im */
315
    } else {
368
    } else {
316
        /* otherwise, indirect call */
369
        /* otherwise, indirect call */
317
        r = gv(RC_INT);
370
        r = gv(RC_INT);
318
        o(0xff); /* call/jmp *r */
371
        o(0xff); /* call/jmp *r */
319
        o(0xd0 + r + (is_jmp << 4));
372
        o(0xd0 + r + (is_jmp << 4));
320
    }
373
    }
321
}
374
}
Line 322... Line 375...
322
 
375
 
-
 
376
static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
-
 
377
static uint8_t fastcallw_regs[2] = { TREG_ECX, TREG_EDX };
-
 
378
 
-
 
379
/* Return the number of registers needed to return the struct, or 0 if
-
 
380
   returning via struct pointer. */
-
 
381
ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int *regsize)
-
 
382
{
-
 
383
#ifdef TCC_TARGET_PE
-
 
384
    int size, align;
-
 
385
 
-
 
386
    *ret_align = 1; // Never have to re-align return values for x86
-
 
387
    *regsize = 4;
-
 
388
    size = type_size(vt, &align);
-
 
389
    if (size > 8) {
-
 
390
        return 0;
-
 
391
    } else if (size > 4) {
-
 
392
        ret->ref = NULL;
-
 
393
        ret->t = VT_LLONG;
-
 
394
        return 1;
-
 
395
    } else {
-
 
396
        ret->ref = NULL;
-
 
397
        ret->t = VT_INT;
-
 
398
        return 1;
-
 
399
    }
-
 
400
#else
-
 
401
    *ret_align = 1; // Never have to re-align return values for x86
-
 
402
    return 0;
-
 
403
#endif
Line 323... Line 404...
323
static uint8_t fastcall_regs[3] = { TREG_EAX, TREG_EDX, TREG_ECX };
404
}
324
 
405
 
325
/* Generate function call. The function address is pushed first, then
406
/* Generate function call. The function address is pushed first, then
326
   all the parameters in call order. This functions pops all the
407
   all the parameters in call order. This functions pops all the
327
   parameters and the function address. */
408
   parameters and the function address. */
328
void gfunc_call(int nb_args)
409
ST_FUNC void gfunc_call(int nb_args)
329
{
410
{
Line 330... Line 411...
330
    int size, align, r, args_size, i, func_call;
411
    int size, align, r, args_size, i, func_call;
Line 377... Line 458...
377
        }
458
        }
378
        vtop--;
459
        vtop--;
379
    }
460
    }
380
    save_regs(0); /* save used temporary registers */
461
    save_regs(0); /* save used temporary registers */
381
    func_sym = vtop->type.ref;
462
    func_sym = vtop->type.ref;
382
    func_call = func_sym->r;
463
    func_call = func_sym->a.func_call;
383
    /* fast call case */
464
    /* fast call case */
384
    if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
465
    if ((func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) ||
-
 
466
        func_call == FUNC_FASTCALLW) {
385
        int fastcall_nb_regs;
467
        int fastcall_nb_regs;
-
 
468
        uint8_t *fastcall_regs_ptr;
-
 
469
        if (func_call == FUNC_FASTCALLW) {
-
 
470
            fastcall_regs_ptr = fastcallw_regs;
-
 
471
            fastcall_nb_regs = 2;
-
 
472
        } else {
-
 
473
            fastcall_regs_ptr = fastcall_regs;
386
        fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
474
            fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
-
 
475
        }
387
        for(i = 0;i < fastcall_nb_regs; i++) {
476
        for(i = 0;i < fastcall_nb_regs; i++) {
388
            if (args_size <= 0)
477
            if (args_size <= 0)
389
                break;
478
                break;
390
            o(0x58 + fastcall_regs[i]); /* pop r */
479
            o(0x58 + fastcall_regs_ptr[i]); /* pop r */
391
            /* XXX: incorrect for struct/floats */
480
            /* XXX: incorrect for struct/floats */
392
            args_size -= 4;
481
            args_size -= 4;
393
        }
482
        }
394
    }
483
    }
-
 
484
#ifndef TCC_TARGET_PE
-
 
485
    else if ((vtop->type.ref->type.t & VT_BTYPE) == VT_STRUCT)
-
 
486
        args_size -= 4;
-
 
487
#endif
395
    gcall_or_jmp(0);
488
    gcall_or_jmp(0);
-
 
489
 
396
    if (args_size && func_sym->r != FUNC_STDCALL)
490
    if (args_size && func_call != FUNC_STDCALL)
397
        gadd_sp(args_size);
491
        gadd_sp(args_size);
398
    vtop--;
492
    vtop--;
399
}
493
}
Line 400... Line 494...
400
 
494
 
Line 403... Line 497...
403
#else
497
#else
404
#define FUNC_PROLOG_SIZE 9
498
#define FUNC_PROLOG_SIZE 9
405
#endif
499
#endif
Line 406... Line 500...
406
 
500
 
407
/* generate function prolog of type 't' */
501
/* generate function prolog of type 't' */
408
void gfunc_prolog(CType *func_type)
502
ST_FUNC void gfunc_prolog(CType *func_type)
409
{
503
{
410
    int addr, align, size, func_call, fastcall_nb_regs;
504
    int addr, align, size, func_call, fastcall_nb_regs;
-
 
505
    int param_index, param_addr;
411
    int param_index, param_addr;
506
    uint8_t *fastcall_regs_ptr;
412
    Sym *sym;
507
    Sym *sym;
Line 413... Line 508...
413
    CType *type;
508
    CType *type;
414
 
509
 
415
    sym = func_type->ref;
510
    sym = func_type->ref;
416
    func_call = sym->r;
511
    func_call = sym->a.func_call;
-
 
512
    addr = 8;
-
 
513
    loc = 0;
417
    addr = 8;
514
    func_vc = 0;
418
    loc = 0;
515
 
-
 
516
    if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
-
 
517
        fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
-
 
518
        fastcall_regs_ptr = fastcall_regs;
-
 
519
    } else if (func_call == FUNC_FASTCALLW) {
419
    if (func_call >= FUNC_FASTCALL1 && func_call <= FUNC_FASTCALL3) {
520
        fastcall_nb_regs = 2;
420
        fastcall_nb_regs = func_call - FUNC_FASTCALL1 + 1;
521
        fastcall_regs_ptr = fastcallw_regs;
-
 
522
    } else {
421
    } else {
523
        fastcall_nb_regs = 0;
422
        fastcall_nb_regs = 0;
524
        fastcall_regs_ptr = NULL;
Line 423... Line 525...
423
    }
525
    }
424
    param_index = 0;
526
    param_index = 0;
425
 
527
 
426
    ind += FUNC_PROLOG_SIZE;
528
    ind += FUNC_PROLOG_SIZE;
427
    func_sub_sp_offset = ind;
529
    func_sub_sp_offset = ind;
-
 
530
    /* if the function returns a structure, then add an
-
 
531
       implicit pointer parameter */
-
 
532
    func_vt = sym->type;
-
 
533
    func_var = (sym->c == FUNC_ELLIPSIS);
-
 
534
#ifdef TCC_TARGET_PE
428
    /* if the function returns a structure, then add an
535
    size = type_size(&func_vt,&align);
-
 
536
    if (((func_vt.t & VT_BTYPE) == VT_STRUCT) && (size > 8)) {
429
       implicit pointer parameter */
537
#else
430
    func_vt = sym->type;
538
    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
431
    if ((func_vt.t & VT_BTYPE) == VT_STRUCT) {
539
#endif
432
        /* XXX: fastcall case ? */
540
        /* XXX: fastcall case ? */
433
        func_vc = addr;
541
        func_vc = addr;
Line 447... Line 555...
447
#endif
555
#endif
448
        if (param_index < fastcall_nb_regs) {
556
        if (param_index < fastcall_nb_regs) {
449
            /* save FASTCALL register */
557
            /* save FASTCALL register */
450
            loc -= 4;
558
            loc -= 4;
451
            o(0x89);     /* movl */
559
            o(0x89);     /* movl */
452
            gen_modrm(fastcall_regs[param_index], VT_LOCAL, NULL, loc);
560
            gen_modrm(fastcall_regs_ptr[param_index], VT_LOCAL, NULL, loc);
453
            param_addr = loc;
561
            param_addr = loc;
454
        } else {
562
        } else {
455
            param_addr = addr;
563
            param_addr = addr;
456
            addr += size;
564
            addr += size;
457
        }
565
        }
458
        sym_push(sym->v & ~SYM_FIELD, type,
566
        sym_push(sym->v & ~SYM_FIELD, type,
459
                 VT_LOCAL | VT_LVAL, param_addr);
567
                 VT_LOCAL | lvalue_type(type->t), param_addr);
460
        param_index++;
568
        param_index++;
461
    }
569
    }
462
    func_ret_sub = 0;
570
    func_ret_sub = 0;
463
    /* pascal type call ? */
571
    /* pascal type call ? */
464
    if (func_call == FUNC_STDCALL)
572
    if (func_call == FUNC_STDCALL)
465
        func_ret_sub = addr - 8;
573
        func_ret_sub = addr - 8;
-
 
574
#ifndef TCC_TARGET_PE
-
 
575
    else if (func_vc)
-
 
576
        func_ret_sub = 4;
-
 
577
#endif
Line -... Line 578...
-
 
578
 
466
 
579
#ifdef CONFIG_TCC_BCHECK
467
    /* leave some room for bound checking code */
580
    /* leave some room for bound checking code */
468
    if (do_bounds_check) {
581
    if (tcc_state->do_bounds_check) {
469
        oad(0xb8, 0); /* lbound section pointer */
582
        oad(0xb8, 0); /* lbound section pointer */
470
        oad(0xb8, 0); /* call to function */
583
        oad(0xb8, 0); /* call to function */
471
        func_bound_offset = lbounds_section->data_offset;
584
        func_bound_offset = lbounds_section->data_offset;
-
 
585
    }
472
    }
586
#endif
Line 473... Line 587...
473
}
587
}
474
 
588
 
475
/* generate function epilog */
589
/* generate function epilog */
476
void gfunc_epilog(void)
590
ST_FUNC void gfunc_epilog(void)
Line 477... Line 591...
477
{
591
{
-
 
592
    addr_t v, saved_ind;
478
    int v, saved_ind;
593
 
479
 
594
#ifdef CONFIG_TCC_BCHECK
480
#ifdef CONFIG_TCC_BCHECK
595
    if (tcc_state->do_bounds_check
481
    if (do_bounds_check && func_bound_offset != lbounds_section->data_offset) {
596
     && func_bound_offset != lbounds_section->data_offset) {
482
        int saved_ind;
597
        addr_t saved_ind;
483
        int *bounds_ptr;
598
        addr_t *bounds_ptr;
484
        Sym *sym, *sym_data;
599
        Sym *sym_data;
485
        /* add end of table info */
600
        /* add end of table info */
486
        bounds_ptr = section_ptr_add(lbounds_section, sizeof(int));
601
        bounds_ptr = section_ptr_add(lbounds_section, sizeof(addr_t));
487
        *bounds_ptr = 0;
602
        *bounds_ptr = 0;
488
        /* generate bound local allocation */
603
        /* generate bound local allocation */
489
        saved_ind = ind;
604
        saved_ind = ind;
490
        ind = func_sub_sp_offset;
605
        ind = func_sub_sp_offset;
491
        sym_data = get_sym_ref(&char_pointer_type, lbounds_section, 
606
        sym_data = get_sym_ref(&char_pointer_type, lbounds_section, 
492
                               func_bound_offset, lbounds_section->data_offset);
607
                               func_bound_offset, lbounds_section->data_offset);
493
        greloc(cur_text_section, sym_data,
608
        greloc(cur_text_section, sym_data,
494
               ind + 1, R_386_32);
-
 
495
        oad(0xb8, 0); /* mov %eax, xxx */
-
 
496
        sym = external_global_sym(TOK___bound_local_new, &func_old_type, 0);
-
 
-
 
609
               ind + 1, R_386_32);
497
        greloc(cur_text_section, sym, 
610
        oad(0xb8, 0); /* mov %eax, xxx */
498
               ind + 1, R_386_PC32);
611
        gen_static_call(TOK___bound_local_new);
499
        oad(0xe8, -4);
612
 
500
        ind = saved_ind;
613
        ind = saved_ind;
501
        /* generate bound check local freeing */
614
        /* generate bound check local freeing */
502
        o(0x5250); /* save returned value, if any */
615
        o(0x5250); /* save returned value, if any */
503
        greloc(cur_text_section, sym_data,
616
        greloc(cur_text_section, sym_data,
504
               ind + 1, R_386_32);
-
 
505
        oad(0xb8, 0); /* mov %eax, xxx */
-
 
506
        sym = external_global_sym(TOK___bound_local_delete, &func_old_type, 0);
-
 
-
 
617
               ind + 1, R_386_32);
507
        greloc(cur_text_section, sym, 
618
        oad(0xb8, 0); /* mov %eax, xxx */
508
               ind + 1, R_386_PC32);
619
        gen_static_call(TOK___bound_local_delete);
509
        oad(0xe8, -4);
620
 
510
        o(0x585a); /* restore returned value, if any */
621
        o(0x585a); /* restore returned value, if any */
511
    }
622
    }
Line 523... Line 634...
523
    v = (-loc + 3) & -4; 
634
    v = (-loc + 3) & -4; 
524
    saved_ind = ind;
635
    saved_ind = ind;
525
    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
636
    ind = func_sub_sp_offset - FUNC_PROLOG_SIZE;
526
#ifdef TCC_TARGET_PE
637
#ifdef TCC_TARGET_PE
527
    if (v >= 4096) {
638
    if (v >= 4096) {
528
        Sym *sym = external_global_sym(TOK___chkstk, &func_old_type, 0);
-
 
529
        oad(0xb8, v); /* mov stacksize, %eax */
639
        oad(0xb8, v); /* mov stacksize, %eax */
530
        oad(0xe8, -4); /* call __chkstk, (does the stackframe too) */
640
        gen_static_call(TOK___chkstk); /* call __chkstk, (does the stackframe too) */
531
        greloc(cur_text_section, sym, ind-4, R_386_PC32);
-
 
532
    } else
641
    } else
533
#endif
642
#endif
534
    {
643
    {
535
        o(0xe58955);  /* push %ebp, mov %esp, %ebp */
644
        o(0xe58955);  /* push %ebp, mov %esp, %ebp */
536
        o(0xec81);  /* sub esp, stacksize */
645
        o(0xec81);  /* sub esp, stacksize */
Line 541... Line 650...
541
    }
650
    }
542
    ind = saved_ind;
651
    ind = saved_ind;
543
}
652
}
Line 544... Line 653...
544
 
653
 
545
/* generate a jump to a label */
654
/* generate a jump to a label */
546
int gjmp(int t)
655
ST_FUNC int gjmp(int t)
547
{
656
{
548
    return psym(0xe9, t);
657
    return psym(0xe9, t);
Line 549... Line 658...
549
}
658
}
550
 
659
 
551
/* generate a jump to a fixed address */
660
/* generate a jump to a fixed address */
552
void gjmp_addr(int a)
661
ST_FUNC void gjmp_addr(int a)
553
{
662
{
554
    int r;
663
    int r;
555
    r = a - ind - 2;
664
    r = a - ind - 2;
Line 560... Line 669...
560
        oad(0xe9, a - ind - 5);
669
        oad(0xe9, a - ind - 5);
561
    }
670
    }
562
}
671
}
Line 563... Line 672...
563
 
672
 
564
/* generate a test. set 'inv' to invert test. Stack entry is popped */
673
/* generate a test. set 'inv' to invert test. Stack entry is popped */
565
int gtst(int inv, int t)
674
ST_FUNC int gtst(int inv, int t)
566
{
-
 
567
    int v, *p;
-
 
568
 
675
{
569
    v = vtop->r & VT_VALMASK;
676
    int v = vtop->r & VT_VALMASK;
570
    if (v == VT_CMP) {
677
    if (v == VT_CMP) {
571
        /* fast case : can jump directly since flags are set */
678
        /* fast case : can jump directly since flags are set */
572
        g(0x0f);
679
        g(0x0f);
573
        t = psym((vtop->c.i - 16) ^ inv, t);
680
        t = psym((vtop->c.i - 16) ^ inv, t);
574
    } else if (v == VT_JMP || v == VT_JMPI) {
681
    } else if (v == VT_JMP || v == VT_JMPI) {
575
        /* && or || optimization */
682
        /* && or || optimization */
576
        if ((v & 1) == inv) {
683
        if ((v & 1) == inv) {
577
            /* insert vtop->c jump list in t */
684
            /* insert vtop->c jump list in t */
578
            p = &vtop->c.i;
685
            uint32_t n1, n = vtop->c.i;
579
            while (*p != 0)
686
            if (n) {
580
                p = (int *)(cur_text_section->data + *p);
687
                while ((n1 = read32le(cur_text_section->data + n)))
-
 
688
                    n = n1;
581
            *p = t;
689
                write32le(cur_text_section->data + n, t);
582
            t = vtop->c.i;
-
 
583
        } else {
-
 
584
            t = gjmp(t);
-
 
585
            gsym(vtop->c.i);
690
                t = vtop->c.i;
586
        }
691
            }
587
    } else {
-
 
588
        if (is_float(vtop->type.t)) {
-
 
589
            vpushi(0);
-
 
590
            gen_op(TOK_NE);
-
 
591
        }
-
 
592
        if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) {
-
 
593
            /* constant jmp optimization */
-
 
594
            if ((vtop->c.i != 0) != inv) 
692
        } else {
595
                t = gjmp(t);
-
 
596
        } else {
693
            t = gjmp(t);
597
            v = gv(RC_INT);
-
 
598
            o(0x85);
-
 
599
            o(0xc0 + v * 9);
-
 
600
            g(0x0f);
-
 
601
            t = psym(0x85 ^ inv, t);
694
            gsym(vtop->c.i);
602
        }
695
        }
603
    }
696
    }
604
    vtop--;
697
    vtop--;
605
    return t;
698
    return t;
Line 606... Line 699...
606
}
699
}
607
 
700
 
608
/* generate an integer binary operation */
701
/* generate an integer binary operation */
609
void gen_opi(int op)
702
ST_FUNC void gen_opi(int op)
Line 610... Line 703...
610
{
703
{
611
    int r, fr, opc, c;
704
    int r, fr, opc, c;
Line 620... Line 713...
620
            vswap();
713
            vswap();
621
            r = gv(RC_INT);
714
            r = gv(RC_INT);
622
            vswap();
715
            vswap();
623
            c = vtop->c.i;
716
            c = vtop->c.i;
624
            if (c == (char)c) {
717
            if (c == (char)c) {
625
                /* XXX: generate inc and dec for smaller code ? */
718
                /* generate inc and dec for smaller code */
-
 
719
                if (c==1 && opc==0) {
-
 
720
                    o (0x40 | r); // inc
-
 
721
                } else if (c==1 && opc==5) {
-
 
722
                    o (0x48 | r); // dec
-
 
723
                } else {
626
                o(0x83);
724
                    o(0x83);
627
                o(0xc0 | (opc << 3) | r);
725
                    o(0xc0 | (opc << 3) | r);
628
                g(c);
726
                    g(c);
-
 
727
                }
629
            } else {
728
            } else {
630
                o(0x81);
729
                o(0x81);
631
                oad(0xc0 | (opc << 3) | r, c);
730
                oad(0xc0 | (opc << 3) | r, c);
632
            }
731
            }
633
        } else {
732
        } else {
Line 738... Line 837...
738
}
837
}
Line 739... Line 838...
739
 
838
 
740
/* generate a floating point operation 'v = t1 op t2' instruction. The
839
/* generate a floating point operation 'v = t1 op t2' instruction. The
741
   two operands are guaranted to have the same floating point type */
840
   two operands are guaranted to have the same floating point type */
742
/* XXX: need to use ST1 too */
841
/* XXX: need to use ST1 too */
743
void gen_opf(int op)
842
ST_FUNC void gen_opf(int op)
744
{
843
{
Line 745... Line 844...
745
    int a, ft, fc, swapped, r;
844
    int a, ft, fc, swapped, r;
746
 
845
 
Line 775... Line 874...
775
            swapped = !swapped;
874
            swapped = !swapped;
776
        else if (op == TOK_EQ || op == TOK_NE)
875
        else if (op == TOK_EQ || op == TOK_NE)
777
            swapped = 0;
876
            swapped = 0;
778
        if (swapped)
877
        if (swapped)
779
            o(0xc9d9); /* fxch %st(1) */
878
            o(0xc9d9); /* fxch %st(1) */
-
 
879
        if (op == TOK_EQ || op == TOK_NE)
780
        o(0xe9da); /* fucompp */
880
            o(0xe9da); /* fucompp */
-
 
881
        else
-
 
882
            o(0xd9de); /* fcompp */
781
        o(0xe0df); /* fnstsw %ax */
883
        o(0xe0df); /* fnstsw %ax */
782
        if (op == TOK_EQ) {
884
        if (op == TOK_EQ) {
783
            o(0x45e480); /* and $0x45, %ah */
885
            o(0x45e480); /* and $0x45, %ah */
784
            o(0x40fC80); /* cmp $0x40, %ah */
886
            o(0x40fC80); /* cmp $0x40, %ah */
785
        } else if (op == TOK_NE) {
887
        } else if (op == TOK_NE) {
Line 821... Line 923...
821
            if (swapped)
923
            if (swapped)
822
                a++;
924
                a++;
823
            break;
925
            break;
824
        }
926
        }
825
        ft = vtop->type.t;
927
        ft = vtop->type.t;
826
        fc = vtop->c.ul;
928
        fc = vtop->c.i;
827
        if ((ft & VT_BTYPE) == VT_LDOUBLE) {
929
        if ((ft & VT_BTYPE) == VT_LDOUBLE) {
828
            o(0xde); /* fxxxp %st, %st(1) */
930
            o(0xde); /* fxxxp %st, %st(1) */
829
            o(0xc1 + (a << 3));
931
            o(0xc1 + (a << 3));
830
        } else {
932
        } else {
831
            /* if saved lvalue, then we must reload it */
933
            /* if saved lvalue, then we must reload it */
Line 833... Line 935...
833
            if ((r & VT_VALMASK) == VT_LLOCAL) {
935
            if ((r & VT_VALMASK) == VT_LLOCAL) {
834
                SValue v1;
936
                SValue v1;
835
                r = get_reg(RC_INT);
937
                r = get_reg(RC_INT);
836
                v1.type.t = VT_INT;
938
                v1.type.t = VT_INT;
837
                v1.r = VT_LOCAL | VT_LVAL;
939
                v1.r = VT_LOCAL | VT_LVAL;
838
                v1.c.ul = fc;
940
                v1.c.i = fc;
839
                load(r, &v1);
941
                load(r, &v1);
840
                fc = 0;
942
                fc = 0;
841
            }
943
            }
Line 842... Line 944...
842
 
944
 
Line 850... Line 952...
850
    }
952
    }
851
}
953
}
Line 852... Line 954...
852
 
954
 
853
/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
955
/* convert integers to fp 't' type. Must handle 'int', 'unsigned int'
854
   and 'long long' cases. */
956
   and 'long long' cases. */
855
void gen_cvt_itof(int t)
957
ST_FUNC void gen_cvt_itof(int t)
856
{
958
{
857
    save_reg(TREG_ST0);
959
    save_reg(TREG_ST0);
858
    gv(RC_INT);
960
    gv(RC_INT);
859
    if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
961
    if ((vtop->type.t & VT_BTYPE) == VT_LLONG) {
Line 879... Line 981...
879
    }
981
    }
880
    vtop->r = TREG_ST0;
982
    vtop->r = TREG_ST0;
881
}
983
}
Line 882... Line 984...
882
 
984
 
883
/* convert fp to int 't' type */
-
 
884
/* XXX: handle long long case */
985
/* convert fp to int 't' type */
885
void gen_cvt_ftoi(int t)
986
ST_FUNC void gen_cvt_ftoi(int t)
886
{
-
 
887
    int r, r2, size;
-
 
888
    Sym *sym;
987
{
889
    CType ushort_type;
-
 
890
 
988
 #ifndef COMMIT_4ad186c5ef61_IS_FIXED
891
    ushort_type.t = VT_SHORT | VT_UNSIGNED;
-
 
892
 
989
    /* a good version but it takes a more time to execute */
893
    gv(RC_FLOAT);
990
    gv(RC_FLOAT);
894
    if (t != VT_INT)
991
    save_reg(TREG_EAX);
895
        size = 8;
-
 
896
    else 
-
 
897
        size = 4;
-
 
898
    
-
 
899
    o(0x2dd9); /* ldcw xxx */
992
    save_reg(TREG_EDX);
900
    sym = external_global_sym(TOK___tcc_int_fpu_control, 
-
 
901
                              &ushort_type, VT_LVAL);
-
 
902
    greloc(cur_text_section, sym, 
-
 
903
           ind, R_386_32);
-
 
904
    gen_le32(0);
-
 
905
    
993
    gen_static_call(TOK___tcc_cvt_ftol);
906
    oad(0xec81, size); /* sub $xxx, %esp */
994
    vtop->r = TREG_EAX; /* mark reg as used */
907
    if (size == 4)
995
    if (t == VT_LLONG)
908
        o(0x1cdb); /* fistpl */
996
        vtop->r2 = TREG_EDX;
909
    else
997
 #else
910
        o(0x3cdf); /* fistpll */
998
    /* a new version with a bug: t2a = 44100312 */
911
    o(0x24);
-
 
912
    o(0x2dd9); /* ldcw xxx */
-
 
913
    sym = external_global_sym(TOK___tcc_fpu_control, 
-
 
914
                              &ushort_type, VT_LVAL);
999
    /*
915
    greloc(cur_text_section, sym, 
-
 
916
           ind, R_386_32);
1000
    #include
917
    gen_le32(0);
-
 
918
 
1001
    int main() {
919
    r = get_reg(RC_INT);
-
 
920
    o(0x58 + r); /* pop r */
1002
	int t1 = 176401255;
921
    if (size == 8) {
-
 
922
        if (t == VT_LLONG) {
1003
	float f = 0.25f;
923
            vtop->r = r; /* mark reg as used */
1004
	int t2a = (int)(t1 * f); // must be 44100313
924
            r2 = get_reg(RC_INT);
1005
	int t2b = (int)(t1 * (float)0.25f);
925
            o(0x58 + r2); /* pop r2 */
-
 
926
            vtop->r2 = r2;
-
 
927
        } else {
-
 
928
            o(0x04c483); /* add $4, %esp */
1006
	printf("t2a=%d t2b=%d \n",t2a,t2b);
929
        }
1007
	return 0;
-
 
1008
    }
-
 
1009
    */
-
 
1010
    int bt = vtop->type.t & VT_BTYPE;
-
 
1011
    if (bt == VT_FLOAT)
-
 
1012
        vpush_global_sym(&func_old_type, TOK___fixsfdi);
-
 
1013
    else if (bt == VT_LDOUBLE)
-
 
1014
        vpush_global_sym(&func_old_type, TOK___fixxfdi);
-
 
1015
    else
-
 
1016
        vpush_global_sym(&func_old_type, TOK___fixdfdi);
-
 
1017
    vswap();
-
 
1018
    gfunc_call(1);
930
    }
1019
    vpushi(0);
-
 
1020
    vtop->r = REG_IRET;
-
 
1021
    vtop->r2 = REG_LRET;
931
    vtop->r = r;
1022
 #endif
Line 932... Line 1023...
932
}
1023
}
933
 
1024
 
934
/* convert from one floating point type to another */
1025
/* convert from one floating point type to another */
935
void gen_cvt_ftof(int t)
1026
ST_FUNC void gen_cvt_ftof(int t)
936
{
1027
{
937
    /* all we have to do on i386 is to put the float in a register */
1028
    /* all we have to do on i386 is to put the float in a register */
Line 938... Line 1029...
938
    gv(RC_FLOAT);
1029
    gv(RC_FLOAT);
939
}
1030
}
940
 
1031
 
941
/* computed goto support */
1032
/* computed goto support */
942
void ggoto(void)
1033
ST_FUNC void ggoto(void)
943
{
1034
{
Line 944... Line 1035...
944
    gcall_or_jmp(1);
1035
    gcall_or_jmp(1);
945
    vtop--;
1036
    vtop--;
Line 946... Line 1037...
946
}
1037
}
947
 
1038
 
948
/* bound check support functions */
1039
/* bound check support functions */
949
#ifdef CONFIG_TCC_BCHECK
-
 
950
 
-
 
951
/* generate a bounded pointer addition */
1040
#ifdef CONFIG_TCC_BCHECK
952
void gen_bounded_ptr_add(void)
1041
 
953
{
1042
/* generate a bounded pointer addition */
954
    Sym *sym;
1043
ST_FUNC void gen_bounded_ptr_add(void)
955
 
1044
{
956
    /* prepare fast i386 function call (args in eax and edx) */
1045
    /* prepare fast i386 function call (args in eax and edx) */
957
    gv2(RC_EAX, RC_EDX);
1046
    gv2(RC_EAX, RC_EDX);
958
    /* save all temporary registers */
-
 
959
    vtop -= 2;
-
 
960
    save_regs(0);
-
 
961
    /* do a fast function call */
1047
    /* save all temporary registers */
962
    sym = external_global_sym(TOK___bound_ptr_add, &func_old_type, 0);
1048
    vtop -= 2;
963
    greloc(cur_text_section, sym, 
1049
    save_regs(0);
964
           ind + 1, R_386_PC32);
1050
    /* do a fast function call */
965
    oad(0xe8, -4);
1051
    gen_static_call(TOK___bound_ptr_add);
966
    /* returned pointer is in eax */
1052
    /* returned pointer is in eax */
Line 967... Line 1053...
967
    vtop++;
1053
    vtop++;
968
    vtop->r = TREG_EAX | VT_BOUNDED;
1054
    vtop->r = TREG_EAX | VT_BOUNDED;
969
    /* address of bounding function call point */
1055
    /* address of bounding function call point */
970
    vtop->c.ul = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel)); 
1056
    vtop->c.i = (cur_text_section->reloc->data_offset - sizeof(Elf32_Rel));
971
}
1057
}
972
 
1058
 
973
/* patch pointer addition in vtop so that pointer dereferencing is
1059
/* patch pointer addition in vtop so that pointer dereferencing is
974
   also tested */
1060
   also tested */
Line 975... Line 1061...
975
void gen_bounded_ptr_deref(void)
1061
ST_FUNC void gen_bounded_ptr_deref(void)
Line 995... Line 1081...
995
    case  4: func = TOK___bound_ptr_indir4; break;
1081
    case  4: func = TOK___bound_ptr_indir4; break;
996
    case  8: func = TOK___bound_ptr_indir8; break;
1082
    case  8: func = TOK___bound_ptr_indir8; break;
997
    case 12: func = TOK___bound_ptr_indir12; break;
1083
    case 12: func = TOK___bound_ptr_indir12; break;
998
    case 16: func = TOK___bound_ptr_indir16; break;
1084
    case 16: func = TOK___bound_ptr_indir16; break;
999
    default:
1085
    default:
1000
        error("unhandled size when derefencing bounded pointer");
1086
        tcc_error("unhandled size when dereferencing bounded pointer");
1001
        func = 0;
1087
        func = 0;
1002
        break;
1088
        break;
1003
    }
1089
    }
Line 1004... Line 1090...
1004
 
1090
 
1005
    /* patch relocation */
1091
    /* patch relocation */
1006
    /* XXX: find a better solution ? */
1092
    /* XXX: find a better solution ? */
1007
    rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.ul);
1093
    rel = (Elf32_Rel *)(cur_text_section->reloc->data + vtop->c.i);
1008
    sym = external_global_sym(func, &func_old_type, 0);
1094
    sym = external_global_sym(func, &func_old_type, 0);
1009
    if (!sym->c)
1095
    if (!sym->c)
1010
        put_extern_sym(sym, NULL, 0, 0);
1096
        put_extern_sym(sym, NULL, 0, 0);
1011
    rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
1097
    rel->r_info = ELF32_R_INFO(sym->c, ELF32_R_TYPE(rel->r_info));
1012
}
1098
}
Line -... Line 1099...
-
 
1099
#endif
-
 
1100
 
-
 
1101
/* Save the stack pointer onto the stack */
-
 
1102
ST_FUNC void gen_vla_sp_save(int addr) {
-
 
1103
    /* mov %esp,addr(%ebp)*/
-
 
1104
    o(0x89);
-
 
1105
    gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
-
 
1106
}
-
 
1107
 
-
 
1108
/* Restore the SP from a location on the stack */
-
 
1109
ST_FUNC void gen_vla_sp_restore(int addr) {
-
 
1110
    o(0x8b);
-
 
1111
    gen_modrm(TREG_ESP, VT_LOCAL, NULL, addr);
-
 
1112
}
-
 
1113
 
-
 
1114
/* Subtract from the stack pointer, and push the resulting value onto the stack */
-
 
1115
ST_FUNC void gen_vla_alloc(CType *type, int align) {
-
 
1116
#ifdef TCC_TARGET_PE
-
 
1117
    /* alloca does more than just adjust %rsp on Windows */
-
 
1118
    vpush_global_sym(&func_old_type, TOK_alloca);
-
 
1119
    vswap(); /* Move alloca ref past allocation size */
-
 
1120
    gfunc_call(1);
-
 
1121
#else
-
 
1122
    int r;
-
 
1123
    r = gv(RC_INT); /* allocation size */
-
 
1124
    /* sub r,%rsp */
-
 
1125
    o(0x2b);
-
 
1126
    o(0xe0 | r);
-
 
1127
    /* We align to 16 bytes rather than align */
-
 
1128
    /* and ~15, %esp */
-
 
1129
    o(0xf0e483);
-
 
1130
    vpop();
-
 
1131
#endif
1013
#endif
1132
}
1014
 
1133
 
1015
/* end of X86 code generator */
1134
/* end of X86 code generator */
-
 
1135
/*************************************************************/