Rev 647 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 647 | Rev 6429 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* |
1 | /* |
2 | * CIL code generator for TCC |
2 | * CIL code generator for TCC |
3 | * |
3 | * |
4 | * Copyright (c) 2002 Fabrice Bellard |
4 | * Copyright (c) 2002 Fabrice Bellard |
5 | * |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
6 | * This library is free software; you can redistribute it and/or |
7 | * it under the terms of the GNU General Public License as published by |
7 | * modify it under the terms of the GNU Lesser General Public |
8 | * the Free Software Foundation; either version 2 of the License, or |
8 | * License as published by the Free Software Foundation; either |
9 | * (at your option) any later version. |
9 | * version 2 of the License, or (at your option) any later version. |
10 | * |
10 | * |
11 | * This program is distributed in the hope that it will be useful, |
11 | * This library is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
14 | * GNU General Public License for more details. |
14 | * Lesser General Public License for more details. |
15 | * |
15 | * |
16 | * You should have received a copy of the GNU General Public License |
16 | * You should have received a copy of the GNU Lesser General Public |
17 | * along with this program; if not, write to the Free Software |
17 | * License along with this library; if not, write to the Free Software |
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ |
19 | */ |
Line 20... | Line 20... | ||
20 | 20 | ||
21 | /* number of available registers */ |
21 | /* number of available registers */ |
Line 39... | Line 39... | ||
39 | REG_ST0 = 0, |
39 | REG_ST0 = 0, |
40 | REG_ST1, |
40 | REG_ST1, |
41 | REG_ST2, |
41 | REG_ST2, |
42 | }; |
42 | }; |
Line 43... | Line 43... | ||
43 | 43 | ||
44 | int reg_classes[NB_REGS] = { |
44 | const int reg_classes[NB_REGS] = { |
45 | /* ST0 */ RC_ST | RC_ST0, |
45 | /* ST0 */ RC_ST | RC_ST0, |
46 | /* ST1 */ RC_ST | RC_ST1, |
46 | /* ST1 */ RC_ST | RC_ST1, |
47 | /* ST2 */ RC_ST, |
47 | /* ST2 */ RC_ST, |
Line 51... | Line 51... | ||
51 | #define REG_IRET REG_ST0 /* single word int return register */ |
51 | #define REG_IRET REG_ST0 /* single word int return register */ |
52 | #define REG_LRET REG_ST0 /* second word return register (for long long) */ |
52 | #define REG_LRET REG_ST0 /* second word return register (for long long) */ |
53 | #define REG_FRET REG_ST0 /* float return register */ |
53 | #define REG_FRET REG_ST0 /* float return register */ |
Line 54... | Line 54... | ||
54 | 54 | ||
55 | /* defined if function parameters must be evaluated in reverse order */ |
55 | /* defined if function parameters must be evaluated in reverse order */ |
Line 56... | Line 56... | ||
56 | //#define INVERT_FUNC_PARAMS |
56 | /* #define INVERT_FUNC_PARAMS */ |
57 | 57 | ||
58 | /* defined if structures are passed as pointers. Otherwise structures |
58 | /* defined if structures are passed as pointers. Otherwise structures |
Line 59... | Line 59... | ||
59 | are directly pushed on stack. */ |
59 | are directly pushed on stack. */ |
60 | //#define FUNC_STRUCT_PARAM_AS_PTR |
60 | /* #define FUNC_STRUCT_PARAM_AS_PTR */ |
Line 61... | Line 61... | ||
61 | 61 | ||
Line 191... | Line 191... | ||
191 | tstr = "float64"; |
191 | tstr = "float64"; |
192 | add_tstr: |
192 | add_tstr: |
193 | pstrcat(buf, buf_size, tstr); |
193 | pstrcat(buf, buf_size, tstr); |
194 | break; |
194 | break; |
195 | case VT_STRUCT: |
195 | case VT_STRUCT: |
196 | error("structures not handled yet"); |
196 | tcc_error("structures not handled yet"); |
197 | break; |
197 | break; |
198 | case VT_FUNC: |
198 | case VT_FUNC: |
199 | s = sym_find((unsigned)t >> VT_STRUCT_SHIFT); |
199 | s = sym_find((unsigned)t >> VT_STRUCT_SHIFT); |
200 | il_type_to_str(buf, buf_size, s->t, varstr); |
200 | il_type_to_str(buf, buf_size, s->t, varstr); |
201 | pstrcat(buf, buf_size, "("); |
201 | pstrcat(buf, buf_size, "("); |
Line 385... | Line 385... | ||
385 | /* push function parameter which is in (vtop->t, vtop->c). Stack entry |
385 | /* push function parameter which is in (vtop->t, vtop->c). Stack entry |
386 | is then popped. */ |
386 | is then popped. */ |
387 | void gfunc_param(GFuncContext *c) |
387 | void gfunc_param(GFuncContext *c) |
388 | { |
388 | { |
389 | if ((vtop->t & VT_BTYPE) == VT_STRUCT) { |
389 | if ((vtop->t & VT_BTYPE) == VT_STRUCT) { |
390 | error("structures passed as value not handled yet"); |
390 | tcc_error("structures passed as value not handled yet"); |
391 | } else { |
391 | } else { |
392 | /* simply push on stack */ |
392 | /* simply push on stack */ |
393 | gv(RC_ST0); |
393 | gv(RC_ST0); |
394 | } |
394 | } |
395 | vtop--; |
395 | vtop--; |
Line 439... | Line 439... | ||
439 | 439 | ||
440 | addr = ARG_BASE; |
440 | addr = ARG_BASE; |
441 | /* if the function returns a structure, then add an |
441 | /* if the function returns a structure, then add an |
442 | implicit pointer parameter */ |
442 | implicit pointer parameter */ |
- | 443 | func_vt = sym->t; |
|
443 | func_vt = sym->t; |
444 | func_var = (sym->c == FUNC_ELLIPSIS); |
444 | if ((func_vt & VT_BTYPE) == VT_STRUCT) { |
445 | if ((func_vt & VT_BTYPE) == VT_STRUCT) { |
445 | func_vc = addr; |
446 | func_vc = addr; |
446 | addr++; |
447 | addr++; |
447 | } |
448 | } |
448 | /* define parameters */ |
449 | /* define parameters */ |
449 | while ((sym = sym->next) != NULL) { |
450 | while ((sym = sym->next) != NULL) { |
450 | u = sym->t; |
451 | u = sym->t; |
451 | sym_push(sym->v & ~SYM_FIELD, u, |
452 | sym_push(sym->v & ~SYM_FIELD, u, |
452 | VT_LOCAL | VT_LVAL, addr); |
453 | VT_LOCAL | lvalue_type(sym->type.t), addr); |
453 | addr++; |
454 | addr++; |
454 | } |
455 | } |
Line 455... | Line 456... | ||
455 | } |
456 | } |
Line 526... | Line 527... | ||
526 | t = vtop->c.i; |
527 | t = vtop->c.i; |
527 | } else { |
528 | } else { |
528 | t = gjmp(t); |
529 | t = gjmp(t); |
529 | gsym(vtop->c.i); |
530 | gsym(vtop->c.i); |
530 | } |
531 | } |
531 | } else { |
- | |
532 | if (is_float(vtop->t)) { |
- | |
533 | vpushi(0); |
- | |
534 | gen_op(TOK_NE); |
- | |
535 | } |
- | |
536 | if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST) { |
- | |
537 | /* constant jmp optimization */ |
- | |
538 | if ((vtop->c.i != 0) != inv) |
- | |
539 | t = gjmp(t); |
- | |
540 | } else { |
- | |
541 | v = gv(RC_INT); |
- | |
542 | t = out_opj(IL_OP_BRTRUE - inv, t); |
- | |
543 | } |
- | |
544 | } |
532 | } |
545 | vtop--; |
533 | vtop--; |
546 | return t; |
534 | return t; |
547 | } |
535 | } |