fltcstoper.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. extern int ResultKnown;
  21. extern char *symbol2str();
  22. fltcstbin(expp, oper, expr)
  23. register struct expr **expp, *expr;
  24. {
  25. /* The operation oper is performed on the constant
  26. expressions *expp(ld) and expr(ct), and the result restored in
  27. *expp.
  28. */
  29. flt_arith o1, o2;
  30. int compar = 0;
  31. int cmpval = 0;
  32. o1 = (*expp)->FL_ARITH;
  33. o2 = expr->FL_ARITH;
  34. ASSERT(is_fp_cst(*expp) && is_fp_cst(expr));
  35. switch (oper) {
  36. case '*':
  37. flt_mul(&o1, &o2, &o1);
  38. break;
  39. case '/':
  40. flt_div(&o1, &o2, &o1);
  41. break;
  42. case '+':
  43. flt_add(&o1, &o2, &o1);
  44. break;
  45. case '-':
  46. flt_sub(&o1, &o2, &o1);
  47. break;
  48. case '<':
  49. case '>':
  50. case LESSEQ:
  51. case GREATEREQ:
  52. case EQUAL:
  53. case NOTEQUAL:
  54. compar++;
  55. cmpval = flt_cmp(&o1, &o2);
  56. switch(oper) {
  57. case '<': cmpval = (cmpval < 0); break;
  58. case '>': cmpval = (cmpval > 0); break;
  59. case LESSEQ: cmpval = (cmpval <= 0); break;
  60. case GREATEREQ: cmpval = (cmpval >= 0); break;
  61. case EQUAL: cmpval = (cmpval == 0); break;
  62. case NOTEQUAL: cmpval = (cmpval != 0); break;
  63. }
  64. break;
  65. default:
  66. /* in case of situations like a += 3.0; where a undefined */
  67. flt_status = 0;
  68. break;
  69. }
  70. switch (flt_status) {
  71. case 0:
  72. case FLT_UNFL: /* ignore underflow */
  73. break;
  74. case FLT_OVFL:
  75. if (!ResultKnown)
  76. expr_warning(expr,"floating point overflow on %s"
  77. , symbol2str(oper));
  78. break;
  79. case FLT_DIV0:
  80. if (!ResultKnown)
  81. expr_error(expr,"division by 0.0");
  82. else
  83. expr_warning(expr,"division by 0.0");
  84. break;
  85. default: /* there can't be another status */
  86. crash("(fltcstoper) bad status");
  87. }
  88. if (compar) {
  89. fill_int_expr(*expp, (arith)cmpval, INT);
  90. } else {
  91. (*expp)->FL_ARITH = o1;
  92. }
  93. (*expp)->ex_flags |= expr->ex_flags;
  94. (*expp)->ex_flags &= ~EX_PARENS;
  95. free_expression(expr);
  96. }