conversion.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. /*
  2. * (c) copyright 1987 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 V E R S I O N - C O D E G E N E R A T O R */
  7. #include "lint.h"
  8. #ifndef LINT
  9. #include "nofloat.h"
  10. #include <em.h>
  11. #include "arith.h"
  12. #include "type.h"
  13. #include "sizes.h"
  14. #include "Lpars.h"
  15. #define T_SIGNED 1
  16. #define T_UNSIGNED 2
  17. #ifndef NOFLOAT
  18. #define T_FLOATING 3
  19. #endif /* NOFLOAT */
  20. /* conversion() generates the EM code for a conversion between
  21. the types char, short, int, long, float, double and pointer.
  22. There are three conversion types: signed, unsigned and floating.
  23. The EM code to obtain this conversion looks like:
  24. LOC sizeof(from_type)
  25. LOC sizeof(to_type)
  26. C??
  27. */
  28. static int convtype();
  29. conversion(from_type, to_type)
  30. register struct type *from_type, *to_type;
  31. {
  32. register arith from_size = from_type->tp_size;
  33. register arith to_size = to_type->tp_size;
  34. int from_cnvtype = convtype(from_type);
  35. int to_cnvtype = convtype(to_type);
  36. if ((int)to_size < (int)word_size) to_size = word_size;
  37. if ((int)from_size == (int)to_size && from_cnvtype == to_cnvtype)
  38. return;
  39. switch (from_cnvtype) {
  40. case T_SIGNED:
  41. switch (to_cnvtype) {
  42. case T_SIGNED:
  43. C_loc(from_size);
  44. C_loc(to_size);
  45. C_cii();
  46. break;
  47. case T_UNSIGNED:
  48. #ifndef NOFLOAT
  49. case T_FLOATING:
  50. #endif /* NOFLOAT */
  51. if ((int)from_size < (int)word_size) {
  52. C_loc(from_size);
  53. C_loc(word_size);
  54. C_cii();
  55. from_size = word_size;
  56. }
  57. C_loc(from_size);
  58. C_loc(to_size);
  59. if (to_cnvtype == T_UNSIGNED) C_ciu();
  60. else C_cif();
  61. break;
  62. }
  63. break;
  64. case T_UNSIGNED:
  65. if ((int)from_size < (int)word_size) from_size = word_size;
  66. C_loc(from_size);
  67. C_loc(to_size);
  68. switch (to_cnvtype) {
  69. case T_SIGNED:
  70. C_cui();
  71. break;
  72. case T_UNSIGNED:
  73. C_cuu();
  74. break;
  75. #ifndef NOFLOAT
  76. case T_FLOATING:
  77. C_cuf();
  78. break;
  79. #endif /* NOFLOAT */
  80. }
  81. break;
  82. #ifndef NOFLOAT
  83. case T_FLOATING:
  84. C_loc(from_size);
  85. C_loc(to_size);
  86. switch (to_cnvtype) {
  87. case T_SIGNED:
  88. C_cfi();
  89. break;
  90. case T_UNSIGNED:
  91. C_cfu();
  92. break;
  93. case T_FLOATING:
  94. C_cff();
  95. break;
  96. }
  97. break;
  98. #endif /* NOFLOAT */
  99. default:
  100. crash("(conversion) illegal type conversion");
  101. /*NOTREACHED*/
  102. }
  103. if ((int)(to_type->tp_size) < (int)word_size
  104. #ifndef NOFLOAT
  105. && to_cnvtype != T_FLOATING
  106. #endif /* NOFLOAT */
  107. ) {
  108. extern long full_mask[];
  109. if (to_cnvtype == T_SIGNED) {
  110. C_loc(to_type->tp_size);
  111. C_loc(word_size);
  112. C_cii();
  113. }
  114. else {
  115. C_loc((arith) full_mask[(int)(to_type->tp_size)]);
  116. C_and(word_size);
  117. }
  118. }
  119. }
  120. /* convtype() returns in which category a given type falls:
  121. signed, unsigned or floating
  122. */
  123. static int
  124. convtype(tp)
  125. register struct type *tp;
  126. {
  127. switch (tp->tp_fund) {
  128. case CHAR:
  129. case SHORT:
  130. case INT:
  131. case ERRONEOUS:
  132. case LONG:
  133. case ENUM:
  134. return tp->tp_unsigned ? T_UNSIGNED : T_SIGNED;
  135. #ifndef NOFLOAT
  136. case FLOAT:
  137. case DOUBLE:
  138. return T_FLOATING;
  139. #endif /* NOFLOAT */
  140. case POINTER:
  141. return T_UNSIGNED;
  142. }
  143. return 0;
  144. }
  145. #endif /* LINT */