From 22ce5f248a43f018a7fe1713245616888fc70081 Mon Sep 17 00:00:00 2001 From: bellard Date: Sun, 17 Mar 2002 11:15:05 +0000 Subject: [PATCH] added floating point constant propagation --- tcc.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/tcc.c b/tcc.c index efbb125..3d8048f 100644 --- a/tcc.c +++ b/tcc.c @@ -2977,8 +2977,9 @@ void gen_opl(int op) } } -/* handle constant optimizations and various machine independant opt */ -void gen_opc(int op) +/* handle integer constant optimizations and various machine + independant opt */ +void gen_opic(int op) { int fc, c1, c2, n; SValue *v1, *v2; @@ -3080,6 +3081,67 @@ void gen_opc(int op) } } +/* generate a floating point operation with constant propagation */ +void gen_opif(int op) +{ + int c1, c2; + SValue *v1, *v2; + long double f1, f2; + + v1 = vtop - 1; + v2 = vtop; + /* currently, we cannot do computations with forward symbols */ + c1 = (v1->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST; + c2 = (v2->r & (VT_VALMASK | VT_LVAL | VT_FORWARD)) == VT_CONST; + if (c1 && c2) { + if (v1->t == VT_FLOAT) { + f1 = v1->c.f; + f2 = v2->c.f; + } else if (v1->t == VT_DOUBLE) { + f1 = v1->c.d; + f2 = v2->c.d; + } else { + f1 = v1->c.ld; + f2 = v2->c.ld; + } + + /* NOTE: we only do constant propagation if finite number (not + NaN or infinity) (ANSI spec) */ + if (!finite(f1) || !finite(f2)) + goto general_case; + + switch(op) { + case '+': f1 += f2; break; + case '-': f1 -= f2; break; + case '*': f1 *= f2; break; + case '/': + if (f2 == 0.0) { + if (const_wanted) + error("division by zero in constant"); + goto general_case; + } + f1 /= f2; + break; + /* XXX: also handles tests ? */ + default: + goto general_case; + } + /* XXX: overflow test ? */ + if (v1->t == VT_FLOAT) { + v1->c.f = f1; + } else if (v1->t == VT_DOUBLE) { + v1->c.d = f1; + } else { + v1->c.ld = f1; + } + vtop--; + } else { + general_case: + gen_opf(op); + } +} + + int pointed_size(int t) { return type_size(pointed_type(t), &t); @@ -3127,7 +3189,7 @@ void gen_op(int op) // check_pointer_types(vtop - 1, vtop); /* XXX: check that types are compatible */ u = pointed_size(t1); - gen_opc(op); + gen_opic(op); /* set to integer type */ vtop->t = VT_INT; vpushi(u); @@ -3160,9 +3222,9 @@ void gen_op(int op) } else #endif { - gen_opc(op); + gen_opic(op); } - /* put again type if gen_opc() swaped operands */ + /* put again type if gen_opic() swaped operands */ vtop->t = t1; } } else if (is_float(bt1) || is_float(bt2)) { @@ -3223,11 +3285,11 @@ void gen_op(int op) else gen_cast(t); if (is_float(t)) - gen_opf(op); + gen_opif(op); else if ((t & VT_BTYPE) == VT_LLONG) gen_opl(op); else - gen_opc(op); + gen_opic(op); if (op >= TOK_ULT && op <= TOK_GT) { /* relationnal op: the result is an int */ vtop->t = VT_INT; @@ -6314,7 +6376,7 @@ int launch_exe(int argc, char **argv) void help(void) { - printf("tcc version 0.9.5 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n" + printf("tcc version 0.9.6 - Tiny C Compiler - Copyright (C) 2001, 2002 Fabrice Bellard\n" "usage: tcc [-Idir] [-Dsym[=val]] [-Usym] [-llib] [-g] [-b]\n" " [-i infile] infile [infile_args...]\n" "\n"