con_float 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. /*
  2. (c) copyright 1988 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. /*
  7. #define CODE_GENERATOR for code generator
  8. #define CODE_EXPANDER for code expander
  9. #define IEEEFLOAT for machines using IEEE floating point format
  10. #define PDPFLOAT for machines using the PDP-11 floating point format
  11. If none of these are defined, the format of the machine on which the
  12. code generator runs is used.
  13. Returns 1 if sz has an illegal value, 2 in case of overflow,
  14. and 0 if all went well.
  15. If neither IEEEFLOAT nor PDPFLOAT are defined, the return value is not
  16. trustworthy.
  17. Unfortunately, the IEEE standard does not define the byte-order.
  18. depends on the #defines
  19. FL_MSL_AT_LOW_ADDRESS 1 if most significant long is at low address
  20. FL_MSW_AT_LOW_ADDRESS 1 if most significant word is at low address
  21. FL_MSB_AT_LOW_ADDRESS 1 if most significant byte is at low address
  22. */
  23. #ifdef IEEEFLOAT
  24. #define USE_FLT
  25. #endif
  26. #ifdef PDPFLOAT
  27. #define USE_FLT
  28. #undef FL_MSL_AT_LOW_ADDRESS
  29. #define FL_MSL_AT_LOW_ADDRESS 1
  30. #undef FL_MSW_AT_LOW_ADDRESS
  31. #define FL_MSW_AT_LOW_ADDRESS 1
  32. #undef FL_MSB_AT_LOW_ADDRESS
  33. #define FL_MSB_AT_LOW_ADDRESS 0
  34. #endif
  35. #define I0 ((FL_MSL_AT_LOW_ADDRESS ? 0 : 4) + (FL_MSW_AT_LOW_ADDRESS ? 0 : 2) \
  36. + (FL_MSB_AT_LOW_ADDRESS ? 0 : 1))
  37. #define I1 ((FL_MSL_AT_LOW_ADDRESS ? 0 : 4) + (FL_MSW_AT_LOW_ADDRESS ? 0 : 2) \
  38. + (FL_MSB_AT_LOW_ADDRESS ? 1 : 0))
  39. #define I2 ((FL_MSL_AT_LOW_ADDRESS ? 0 : 4) + (FL_MSW_AT_LOW_ADDRESS ? 2 : 0) \
  40. + (FL_MSB_AT_LOW_ADDRESS ? 0 : 1))
  41. #define I3 ((FL_MSL_AT_LOW_ADDRESS ? 0 : 4) + (FL_MSW_AT_LOW_ADDRESS ? 2 : 0) \
  42. + (FL_MSB_AT_LOW_ADDRESS ? 1 : 0))
  43. #define I4 ((FL_MSL_AT_LOW_ADDRESS ? 4 : 0) + (FL_MSW_AT_LOW_ADDRESS ? 0 : 2) \
  44. + (FL_MSB_AT_LOW_ADDRESS ? 0 : 1))
  45. #define I5 ((FL_MSL_AT_LOW_ADDRESS ? 4 : 0) + (FL_MSW_AT_LOW_ADDRESS ? 0 : 2) \
  46. + (FL_MSB_AT_LOW_ADDRESS ? 1 : 0))
  47. #define I6 ((FL_MSL_AT_LOW_ADDRESS ? 4 : 0) + (FL_MSW_AT_LOW_ADDRESS ? 2 : 0) \
  48. + (FL_MSB_AT_LOW_ADDRESS ? 0 : 1))
  49. #define I7 ((FL_MSL_AT_LOW_ADDRESS ? 4 : 0) + (FL_MSW_AT_LOW_ADDRESS ? 2 : 0) \
  50. + (FL_MSB_AT_LOW_ADDRESS ? 1 : 0))
  51. #ifndef USE_FLT
  52. static int float_cst(char *str, int sz, char *buf)
  53. {
  54. int i;
  55. char *p;
  56. float fl;
  57. double f;
  58. double atof();
  59. if (sz!= 4 && sz!= 8) {
  60. return 1;
  61. }
  62. f = atof(str);
  63. if (sz == 4) {
  64. fl = f;
  65. p = (char *) &fl;
  66. }
  67. else {
  68. p = (char *) &f;
  69. }
  70. for (i = sz; i; i--) {
  71. *buf++ = *p++;
  72. }
  73. return 0;
  74. }
  75. #else /* USE_FLT */
  76. #include <ctype.h>
  77. #include <flt_arith.h>
  78. int float_cst(char *str, int sz, char *buf)
  79. {
  80. int overflow = 0;
  81. flt_arith e;
  82. if (sz!= 4 && sz!= 8) {
  83. return 1;
  84. }
  85. flt_str2flt(str, &e);
  86. #ifdef IEEEFLOAT
  87. if (sz == 4) {
  88. #endif
  89. #ifdef PDPFLOAT
  90. e.flt_exp += 129;
  91. #else
  92. e.flt_exp += 127;
  93. #endif
  94. if (e.flt_mantissa.flt_h_32 == 0) e.flt_exp = 0;
  95. #ifdef IEEEFLOAT
  96. if (e.flt_mantissa.flt_h_32 & 0x80) {
  97. /* rounding */
  98. if ((e.flt_mantissa.flt_h_32 & 0xffffff00) == 0xffffff00) {
  99. e.flt_exp++;
  100. e.flt_mantissa.flt_h_32 = 0x80000000;
  101. }
  102. else {
  103. e.flt_mantissa.flt_h_32 += 0x80;
  104. }
  105. }
  106. if (e.flt_exp >= 255) {
  107. overflow = 1;
  108. e.flt_exp = 255;
  109. e.flt_mantissa.flt_h_32 = e.flt_mantissa.flt_l_32 = 0;
  110. }
  111. if (e.flt_exp <= 0) {
  112. flt_b64_sft(&(e.flt_mantissa), 1);
  113. if (e.flt_exp < 0) {
  114. flt_b64_sft(&(e.flt_mantissa), -e.flt_exp);
  115. e.flt_exp = 0;
  116. }
  117. }
  118. #endif
  119. #ifndef IEEEFLOAT
  120. if (sz == 4 && (e.flt_mantissa.flt_h_32 & 0x80)) {
  121. /* rounding */
  122. if ((e.flt_mantissa.flt_h_32 & 0xffffff00) == 0xffffff00) {
  123. e.flt_exp++;
  124. e.flt_mantissa.flt_h_32 = 0x80000000;
  125. }
  126. else {
  127. e.flt_mantissa.flt_h_32 += 0x80;
  128. }
  129. }
  130. if (sz == 8 && (e.flt_mantissa.flt_l_32 & 0x80)) {
  131. /* rounding */
  132. if ((e.flt_mantissa.flt_l_32 & 0xffffff00) == 0xffffff00) {
  133. e.flt_mantissa.flt_l_32 = 0;
  134. if (e.flt_mantissa.flt_h_32 == 0xffffffff) {
  135. e.flt_exp++;
  136. e.flt_mantissa.flt_h_32 = 0x80000000;
  137. }
  138. else e.flt_mantissa.flt_h_32++;
  139. }
  140. else {
  141. e.flt_mantissa.flt_l_32 += 0x80;
  142. }
  143. }
  144. if (e.flt_exp > 255) {
  145. overflow = 1;
  146. e.flt_exp = 255;
  147. e.flt_mantissa.flt_h_32 = e.flt_mantissa.flt_l_32 = 0xffffffff;
  148. }
  149. #endif
  150. buf[I0] = (e.flt_sign << 7) | (e.flt_exp >> 1);
  151. buf[I1] = ((e.flt_exp&1) << 7) |
  152. ((e.flt_mantissa.flt_h_32 & 0x7fffffff) >> 24);
  153. buf[I2] = e.flt_mantissa.flt_h_32 >> 16;
  154. buf[I3] = e.flt_mantissa.flt_h_32 >> 8;
  155. #ifndef IEEEFLOAT
  156. if (sz == 8) {
  157. buf[I4] = e.flt_mantissa.flt_h_32;
  158. buf[I5] = e.flt_mantissa.flt_l_32 >> 24;
  159. buf[I6] = e.flt_mantissa.flt_l_32 >> 16;
  160. buf[I7] = e.flt_mantissa.flt_l_32 >> 8;
  161. flt_b64_sft(&(e.flt_mantissa), -56);
  162. }
  163. else
  164. #endif
  165. flt_b64_sft(&(e.flt_mantissa), -24);
  166. #ifdef IEEEFLOAT
  167. }
  168. else {
  169. e.flt_exp += 1023;
  170. if (e.flt_mantissa.flt_h_32 == 0) e.flt_exp = 0;
  171. if (e.flt_mantissa.flt_l_32 & 0x400) {
  172. /* rounding */
  173. if ((e.flt_mantissa.flt_l_32 & 0xfffff800) == 0xfffff800) {
  174. e.flt_mantissa.flt_l_32 = 0;
  175. if (e.flt_mantissa.flt_h_32 == 0xffffffff) {
  176. e.flt_exp++;
  177. e.flt_mantissa.flt_h_32 = 0x80000000;
  178. }
  179. else e.flt_mantissa.flt_h_32++;
  180. }
  181. else {
  182. e.flt_mantissa.flt_l_32 += 0x400;
  183. }
  184. }
  185. if (e.flt_exp >= 2047) {
  186. overflow = 1;
  187. e.flt_exp = 2047;
  188. e.flt_mantissa.flt_h_32 = e.flt_mantissa.flt_l_32 = 0;
  189. }
  190. if (e.flt_exp <= 0) {
  191. flt_b64_sft(&(e.flt_mantissa), 1);
  192. if (e.flt_exp < 0) {
  193. flt_b64_sft(&(e.flt_mantissa), -e.flt_exp);
  194. e.flt_exp = 0;
  195. }
  196. }
  197. buf[I0] = (e.flt_sign << 7) | (e.flt_exp >> 4);
  198. buf[I1] = ((e.flt_exp & 017)<< 4) | ((e.flt_mantissa.flt_h_32 >> 27) & 017);
  199. buf[I2] = e.flt_mantissa.flt_h_32 >> 19;
  200. buf[I3] = e.flt_mantissa.flt_h_32 >> 11;
  201. buf[I4] = e.flt_mantissa.flt_h_32 >> 3;
  202. buf[I5] = (e.flt_mantissa.flt_h_32 << 5) | ((e.flt_mantissa.flt_l_32 >> 27) & 037);
  203. buf[I6] = e.flt_mantissa.flt_l_32 >> 19;
  204. buf[I7] = e.flt_mantissa.flt_l_32 >> 11;
  205. flt_b64_sft(&(e.flt_mantissa), -53);
  206. }
  207. #endif
  208. #if ! FL_MSL_AT_LOW_ADDRESS
  209. if (sz == 4) {
  210. buf[I4] = buf[I0];
  211. buf[I5] = buf[I1];
  212. buf[I6] = buf[I2];
  213. buf[I7] = buf[I3];
  214. }
  215. #endif
  216. if (overflow) {
  217. return 2;
  218. }
  219. return 0;
  220. }
  221. #endif /* USE_FLT */
  222. #ifdef CODE_GENERATOR
  223. void con_float()
  224. {
  225. char buf[8];
  226. int rval = float_cst(str, (int)argval, buf);
  227. int i;
  228. if (rval == 1) {
  229. fprintf(stderr,"float constant size = %d\n",(int)argval);
  230. fatal("bad fcon size");
  231. }
  232. fprintf(codefile,"!float %s sz %d\n", str, (int)argval);
  233. if (rval == 2) {
  234. fprintf(stderr, "Warning: overflow in floating point constant %s\n", str);
  235. }
  236. fprintf(codefile, ".data1 0%o", buf[0] & 0377);
  237. for (i = 1; i < (int)argval; i++) {
  238. fprintf(codefile, ",0%o", buf[i] & 0377);
  239. }
  240. putc('\n', codefile);
  241. }
  242. #endif /* CODE_GENERATOR */
  243. #ifdef CODE_EXPANDER
  244. void con_float(char *str, arith argval)
  245. {
  246. char buf[8];
  247. int rval = float_cst(str, (int)argval, buf);
  248. int i;
  249. if (rval == 1) {
  250. argval = 8;
  251. rval = float_cst(str, 8, buf);
  252. }
  253. for (i = 0; i < (int)argval; i++) {
  254. gen1(buf[i]);
  255. }
  256. }
  257. #endif /* CODE_EXPANDER */