fltcstoper.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * (c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3. * See the copyright notice in the ACK home directory, in the file "Copyright".
  4. */
  5. /* $Id$ */
  6. /* 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 */
  7. /* F O R F L O A T I N G P O I N T N U M B E R S */
  8. #include "debug.h"
  9. #include "assert.h"
  10. #include <alloc.h>
  11. #include "trgt_sizes.h"
  12. #include "idf.h"
  13. #include <flt_arith.h>
  14. #include "arith.h"
  15. #include "type.h"
  16. #include "label.h"
  17. #include "expr.h"
  18. #include "sizes.h"
  19. #include "Lpars.h"
  20. #include "cstoper.h"
  21. #include <symbol2str.h>
  22. extern int ResultKnown;
  23. fltcstbin(expp, oper, expr)
  24. register struct expr **expp, *expr;
  25. {
  26. /* The operation oper is performed on the constant
  27. expressions *expp(ld) and expr(ct), and the result restored in
  28. *expp.
  29. */
  30. flt_arith o1, o2;
  31. int compar = 0;
  32. int cmpval = 0;
  33. o1 = (*expp)->FL_ARITH;
  34. o2 = expr->FL_ARITH;
  35. ASSERT(is_fp_cst(*expp) && is_fp_cst(expr));
  36. switch (oper) {
  37. case '*':
  38. flt_mul(&o1, &o2, &o1);
  39. break;
  40. case '/':
  41. flt_div(&o1, &o2, &o1);
  42. break;
  43. case '+':
  44. flt_add(&o1, &o2, &o1);
  45. break;
  46. case '-':
  47. flt_sub(&o1, &o2, &o1);
  48. break;
  49. case '<':
  50. case '>':
  51. case LESSEQ:
  52. case GREATEREQ:
  53. case EQUAL:
  54. case NOTEQUAL:
  55. compar++;
  56. cmpval = flt_cmp(&o1, &o2);
  57. switch(oper) {
  58. case '<': cmpval = (cmpval < 0); break;
  59. case '>': cmpval = (cmpval > 0); break;
  60. case LESSEQ: cmpval = (cmpval <= 0); break;
  61. case GREATEREQ: cmpval = (cmpval >= 0); break;
  62. case EQUAL: cmpval = (cmpval == 0); break;
  63. case NOTEQUAL: cmpval = (cmpval != 0); break;
  64. }
  65. break;
  66. default:
  67. /* in case of situations like a += 3.0; where a undefined */
  68. flt_status = 0;
  69. break;
  70. }
  71. switch (flt_status) {
  72. case 0:
  73. case FLT_UNFL: /* ignore underflow */
  74. break;
  75. case FLT_OVFL:
  76. if (!ResultKnown)
  77. expr_warning(expr,"floating point overflow on %s"
  78. , symbol2str(oper));
  79. break;
  80. case FLT_DIV0:
  81. if (!ResultKnown)
  82. expr_error(expr,"division by 0.0");
  83. else
  84. expr_warning(expr,"division by 0.0");
  85. break;
  86. default: /* there can't be another status */
  87. crash("(fltcstoper) bad status");
  88. }
  89. if (compar) {
  90. fill_int_expr(*expp, (arith)cmpval, INT);
  91. } else {
  92. (*expp)->FL_ARITH = o1;
  93. }
  94. (*expp)->ex_flags |= expr->ex_flags;
  95. (*expp)->ex_flags &= ~EX_PARENS;
  96. free_expression(expr);
  97. }