conversion.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /* $Header$ */
  2. /* C O N V E R S I O N - C O D E G E N E R A T O R */
  3. #include "arith.h"
  4. #include "type.h"
  5. #include "em.h"
  6. #include "sizes.h"
  7. #include "Lpars.h"
  8. #define T_SIGNED 1
  9. #define T_UNSIGNED 2
  10. #define T_FLOATING 3
  11. /* conversion() generates the EM code for a conversion between
  12. the types char, short, int, long, float, double and pointer.
  13. In case of integral type, the notion signed / unsigned is
  14. taken into account.
  15. The EM code to obtain this conversion looks like:
  16. LOC sizeof(from_type)
  17. LOC sizeof(to_type)
  18. C??
  19. */
  20. conversion(from_type, to_type)
  21. struct type *from_type, *to_type;
  22. {
  23. arith from_size;
  24. arith to_size;
  25. if (from_type == to_type) { /* a little optimisation */
  26. return;
  27. }
  28. from_size = from_type->tp_size;
  29. to_size = to_type->tp_size;
  30. switch (fundamental(from_type)) {
  31. case T_SIGNED:
  32. switch (fundamental(to_type)) {
  33. case T_SIGNED:
  34. C_loc(from_size);
  35. C_loc(to_size < word_size ? word_size : to_size);
  36. C_cii();
  37. break;
  38. case T_UNSIGNED:
  39. C_loc(from_size < word_size ? word_size : from_size);
  40. C_loc(to_size < word_size ? word_size : to_size);
  41. C_ciu();
  42. break;
  43. case T_FLOATING:
  44. C_loc(from_size < word_size ? word_size : from_size);
  45. C_loc(to_size < word_size ? word_size : to_size);
  46. C_cif();
  47. break;
  48. }
  49. break;
  50. case T_UNSIGNED:
  51. C_loc(from_size < word_size ? word_size : from_size);
  52. C_loc(to_size < word_size ? word_size : to_size);
  53. switch (fundamental(to_type)) {
  54. case T_SIGNED:
  55. C_cui();
  56. break;
  57. case T_UNSIGNED:
  58. C_cuu();
  59. break;
  60. case T_FLOATING:
  61. C_cuf();
  62. break;
  63. }
  64. break;
  65. case T_FLOATING:
  66. C_loc(from_size < word_size ? word_size : from_size);
  67. C_loc(to_size < word_size ? word_size : to_size);
  68. switch (fundamental(to_type)) {
  69. case T_SIGNED:
  70. C_cfi();
  71. break;
  72. case T_UNSIGNED:
  73. C_cfu();
  74. break;
  75. case T_FLOATING:
  76. C_cff();
  77. break;
  78. }
  79. break;
  80. default:
  81. crash("(conversion) illegal type conversion");
  82. }
  83. }
  84. /* fundamental() returns in which category a given type falls:
  85. signed, unsigned or floating
  86. */
  87. int
  88. fundamental(tp)
  89. struct type *tp;
  90. {
  91. switch (tp->tp_fund) {
  92. case CHAR:
  93. case SHORT:
  94. case INT:
  95. case LONG:
  96. case ENUM:
  97. return tp->tp_unsigned ? T_UNSIGNED : T_SIGNED;
  98. case FLOAT:
  99. case DOUBLE:
  100. return T_FLOATING;
  101. case POINTER: /* pointer : signed / unsigned ??? */
  102. return T_SIGNED;
  103. }
  104. return 0;
  105. }