fltcstoper.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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. /* $Header$ */
  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. case '%':
  66. case LEFT:
  67. case RIGHT:
  68. case '&':
  69. case '|':
  70. case '^':
  71. /*
  72. expr_error(*expp, "floating operand for %s", symbol2str(oper));
  73. break;
  74. */
  75. default:
  76. crash("(fltcstoper) bad operator %s", symbol2str(oper));
  77. /*NOTREACHED*/
  78. }
  79. switch (flt_status) {
  80. case 0:
  81. case FLT_UNFL:
  82. break;
  83. case FLT_OVFL:
  84. if (!ResultKnown)
  85. expr_warning(expr,"floating point overflow on %s"
  86. , symbol2str(oper));
  87. break;
  88. case FLT_DIV0:
  89. if (!ResultKnown)
  90. expr_error(expr,"division by 0.0");
  91. else
  92. expr_warning(expr,"division by 0.0");
  93. break;
  94. default: /* there can't be another status */
  95. crash("(fltcstoper) bad status");
  96. }
  97. if ((*expp)->FL_VALUE) free((*expp)->FL_VALUE);
  98. (*expp)->FL_VALUE = 0;
  99. if (compar) {
  100. fill_int_expr(*expp, (arith)cmpval, INT);
  101. } else {
  102. (*expp)->FL_ARITH = o1;
  103. }
  104. (*expp)->ex_flags |= expr->ex_flags;
  105. (*expp)->ex_flags &= ~EX_PARENS;
  106. free_expression(expr);
  107. }