123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- /*
- * (c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
- * See the copyright notice in the ACK home directory, in the file "Copyright".
- */
- /* $Id$ */
- /* C O N S T A N T E X P R E S S I O N H A N D L I N G */
- /* F O R F L O A T I N G P O I N T N U M B E R S */
- #include "debug.h"
- #include "assert.h"
- #include <alloc.h>
- #include "trgt_sizes.h"
- #include "idf.h"
- #include <flt_arith.h>
- #include "arith.h"
- #include "type.h"
- #include "label.h"
- #include "expr.h"
- #include "sizes.h"
- #include "Lpars.h"
- #include "cstoper.h"
- #include <symbol2str.h>
- extern int ResultKnown;
- fltcstbin(expp, oper, expr)
- register struct expr **expp, *expr;
- {
- /* The operation oper is performed on the constant
- expressions *expp(ld) and expr(ct), and the result restored in
- *expp.
- */
- flt_arith o1, o2;
- int compar = 0;
- int cmpval = 0;
- o1 = (*expp)->FL_ARITH;
- o2 = expr->FL_ARITH;
- ASSERT(is_fp_cst(*expp) && is_fp_cst(expr));
- switch (oper) {
- case '*':
- flt_mul(&o1, &o2, &o1);
- break;
- case '/':
- flt_div(&o1, &o2, &o1);
- break;
- case '+':
- flt_add(&o1, &o2, &o1);
- break;
- case '-':
- flt_sub(&o1, &o2, &o1);
- break;
- case '<':
- case '>':
- case LESSEQ:
- case GREATEREQ:
- case EQUAL:
- case NOTEQUAL:
- compar++;
- cmpval = flt_cmp(&o1, &o2);
- switch(oper) {
- case '<': cmpval = (cmpval < 0); break;
- case '>': cmpval = (cmpval > 0); break;
- case LESSEQ: cmpval = (cmpval <= 0); break;
- case GREATEREQ: cmpval = (cmpval >= 0); break;
- case EQUAL: cmpval = (cmpval == 0); break;
- case NOTEQUAL: cmpval = (cmpval != 0); break;
- }
- break;
- default:
- /* in case of situations like a += 3.0; where a undefined */
- flt_status = 0;
- break;
- }
- switch (flt_status) {
- case 0:
- case FLT_UNFL: /* ignore underflow */
- break;
- case FLT_OVFL:
- if (!ResultKnown)
- expr_warning(expr,"floating point overflow on %s"
- , symbol2str(oper));
- break;
- case FLT_DIV0:
- if (!ResultKnown)
- expr_error(expr,"division by 0.0");
- else
- expr_warning(expr,"division by 0.0");
- break;
- default: /* there can't be another status */
- crash("(fltcstoper) bad status");
- }
- if (compar) {
- fill_int_expr(*expp, (arith)cmpval, INT);
- } else {
- (*expp)->FL_ARITH = o1;
- }
- (*expp)->ex_flags |= expr->ex_flags;
- (*expp)->ex_flags &= ~EX_PARENS;
- free_expression(expr);
- }
|