atof-m68k.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492
  1. /* atof_m68k.c - turn a Flonum into a 68020 floating point number
  2. Copyright (C) 1987 Free Software Foundation, Inc.
  3. This file is part of GAS, the GNU Assembler.
  4. GAS is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 1, or (at your option)
  7. any later version.
  8. GAS is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GAS; see the file COPYING. If not, write to
  14. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  15. #include "flonum.h"
  16. #ifdef USG
  17. #define bzero(s,n) memset(s,0,n)
  18. #endif
  19. extern FLONUM_TYPE generic_floating_point_number; /* Flonums returned here. */
  20. #define NULL (0)
  21. extern char EXP_CHARS[];
  22. /* Precision in LittleNums. */
  23. #define MAX_PRECISION (6)
  24. #define F_PRECISION (2)
  25. #define D_PRECISION (4)
  26. #define X_PRECISION (6)
  27. #define P_PRECISION (6)
  28. /* Length in LittleNums of guard bits. */
  29. #define GUARD (2)
  30. static unsigned long int mask [] = {
  31. 0x00000000,
  32. 0x00000001,
  33. 0x00000003,
  34. 0x00000007,
  35. 0x0000000f,
  36. 0x0000001f,
  37. 0x0000003f,
  38. 0x0000007f,
  39. 0x000000ff,
  40. 0x000001ff,
  41. 0x000003ff,
  42. 0x000007ff,
  43. 0x00000fff,
  44. 0x00001fff,
  45. 0x00003fff,
  46. 0x00007fff,
  47. 0x0000ffff,
  48. 0x0001ffff,
  49. 0x0003ffff,
  50. 0x0007ffff,
  51. 0x000fffff,
  52. 0x001fffff,
  53. 0x003fffff,
  54. 0x007fffff,
  55. 0x00ffffff,
  56. 0x01ffffff,
  57. 0x03ffffff,
  58. 0x07ffffff,
  59. 0x0fffffff,
  60. 0x1fffffff,
  61. 0x3fffffff,
  62. 0x7fffffff,
  63. 0xffffffff
  64. };
  65. static int bits_left_in_littlenum;
  66. static int littlenums_left;
  67. static LITTLENUM_TYPE * littlenum_pointer;
  68. static int
  69. next_bits (number_of_bits)
  70. int number_of_bits;
  71. {
  72. int return_value;
  73. if(!littlenums_left)
  74. return 0;
  75. if (number_of_bits >= bits_left_in_littlenum)
  76. {
  77. return_value = mask [bits_left_in_littlenum] & *littlenum_pointer;
  78. number_of_bits -= bits_left_in_littlenum;
  79. return_value <<= number_of_bits;
  80. if(--littlenums_left) {
  81. bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS - number_of_bits;
  82. littlenum_pointer --;
  83. return_value |= (*littlenum_pointer>>bits_left_in_littlenum) & mask[number_of_bits];
  84. }
  85. }
  86. else
  87. {
  88. bits_left_in_littlenum -= number_of_bits;
  89. return_value = mask [number_of_bits] & (*littlenum_pointer>>bits_left_in_littlenum);
  90. }
  91. return (return_value);
  92. }
  93. /* Num had better be less than LITTLENUM_NUMBER_OF_BITS */
  94. static int
  95. unget_bits(num)
  96. {
  97. if(!littlenums_left) {
  98. ++littlenum_pointer;
  99. ++littlenums_left;
  100. bits_left_in_littlenum=num;
  101. } else if(bits_left_in_littlenum+num>LITTLENUM_NUMBER_OF_BITS) {
  102. bits_left_in_littlenum= num-(LITTLENUM_NUMBER_OF_BITS-bits_left_in_littlenum);
  103. ++littlenum_pointer;
  104. ++littlenums_left;
  105. } else
  106. bits_left_in_littlenum+=num;
  107. }
  108. static void
  109. make_invalid_floating_point_number (words)
  110. LITTLENUM_TYPE * words;
  111. {
  112. as_warn("cannot create floating-point number");
  113. words[0]= ((unsigned)-1)>>1; /* Zero the leftmost bit */
  114. words[1]= -1;
  115. words[2]= -1;
  116. words[3]= -1;
  117. words[4]= -1;
  118. words[5]= -1;
  119. }
  120. /***********************************************************************\
  121. * Warning: this returns 16-bit LITTLENUMs. It is up to the caller *
  122. * to figure out any alignment problems and to conspire for the *
  123. * bytes/word to be emitted in the right order. Bigendians beware! *
  124. * *
  125. \***********************************************************************/
  126. char * /* Return pointer past text consumed. */
  127. atof_m68k (str, what_kind, words)
  128. char * str; /* Text to convert to binary. */
  129. char what_kind; /* 'd', 'f', 'g', 'h' */
  130. LITTLENUM_TYPE * words; /* Build the binary here. */
  131. {
  132. LITTLENUM_TYPE bits [MAX_PRECISION + MAX_PRECISION + GUARD];
  133. /* Extra bits for zeroed low-order bits. */
  134. /* The 1st MAX_PRECISION are zeroed, */
  135. /* the last contain flonum bits. */
  136. char * return_value;
  137. int precision; /* Number of 16-bit words in the format. */
  138. long int exponent_bits;
  139. return_value = str;
  140. generic_floating_point_number.low = bits + MAX_PRECISION;
  141. generic_floating_point_number.high = NULL;
  142. generic_floating_point_number.leader = NULL;
  143. generic_floating_point_number.exponent = NULL;
  144. generic_floating_point_number.sign = '\0';
  145. /* Use more LittleNums than seems */
  146. /* necessary: the highest flonum may have */
  147. /* 15 leading 0 bits, so could be useless. */
  148. bzero (bits, sizeof(LITTLENUM_TYPE) * MAX_PRECISION);
  149. switch(what_kind) {
  150. case 'f':
  151. case 'F':
  152. case 's':
  153. case 'S':
  154. precision = F_PRECISION;
  155. exponent_bits = 8;
  156. break;
  157. case 'd':
  158. case 'D':
  159. case 'r':
  160. case 'R':
  161. precision = D_PRECISION;
  162. exponent_bits = 11;
  163. break;
  164. case 'x':
  165. case 'X':
  166. case 'e':
  167. case 'E':
  168. precision = X_PRECISION;
  169. exponent_bits = 15;
  170. break;
  171. case 'p':
  172. case 'P':
  173. precision = P_PRECISION;
  174. exponent_bits= -1;
  175. break;
  176. default:
  177. make_invalid_floating_point_number (words);
  178. return NULL;
  179. }
  180. generic_floating_point_number.high = generic_floating_point_number.low + precision - 1 + GUARD;
  181. if (atof_generic (& return_value, ".", EXP_CHARS, & generic_floating_point_number)) {
  182. /* as_warn("Error converting floating point number (Exponent overflow?)"); */
  183. make_invalid_floating_point_number (words);
  184. return NULL;
  185. }
  186. gen_to_words(words, precision, exponent_bits);
  187. return return_value;
  188. }
  189. char *
  190. print_gen(gen)
  191. FLONUM_TYPE *gen;
  192. {
  193. FLONUM_TYPE f;
  194. LITTLENUM_TYPE arr[10];
  195. double dv;
  196. float fv;
  197. static char sbuf[40];
  198. f=generic_floating_point_number;
  199. generic_floating_point_number= *gen;
  200. gen_to_words(&arr[0],4,11);
  201. bcopy(&arr[0],&dv,sizeof(double));
  202. sprintf(sbuf,"%x %x %x %x %.14G ",arr[0],arr[1],arr[2],arr[3],dv);
  203. gen_to_words(&arr[0],2,8);
  204. bcopy(&arr[0],&fv,sizeof(float));
  205. sprintf(sbuf+strlen(sbuf),"%x %x %.12g\n",arr[0],arr[1],fv);
  206. generic_floating_point_number=f;
  207. return sbuf;
  208. }
  209. /* Turn generic_floating_point_number into a real float/double/extended */
  210. gen_to_words(words,precision,exponent_bits)
  211. LITTLENUM_TYPE *words;
  212. long int exponent_bits;
  213. int precision;
  214. {
  215. int return_value=0;
  216. long int exponent_1;
  217. long int exponent_2;
  218. long int exponent_3;
  219. long int exponent_4;
  220. int exponent_skippage;
  221. LITTLENUM_TYPE word1;
  222. LITTLENUM_TYPE * lp;
  223. if (generic_floating_point_number.low > generic_floating_point_number.leader) {
  224. /* 0.0e0 seen. */
  225. bzero (words, sizeof(LITTLENUM_TYPE) * precision);
  226. return return_value;
  227. }
  228. /* NaN: Do the right thing */
  229. if(generic_floating_point_number.sign==0) {
  230. if(precision==F_PRECISION) {
  231. words[0]=0xffc0;
  232. words[1]=0x0007;
  233. } else {
  234. words[0]=0x7ff0;
  235. words[1]=0;
  236. words[2]=0xffff;
  237. words[3]=0xffff;
  238. }
  239. return return_value;
  240. } else if(generic_floating_point_number.sign=='P') {
  241. /* +INF: Do the right thing */
  242. if(precision==F_PRECISION) {
  243. words[0]=0x7f80;
  244. words[1]=0;
  245. } else {
  246. words[0]=0x7ff0;
  247. words[1]=0;
  248. words[2]=0;
  249. words[3]=0;
  250. }
  251. return return_value;
  252. } else if(generic_floating_point_number.sign=='N') {
  253. /* Negative INF */
  254. if(precision==F_PRECISION) {
  255. words[0]=0xff80;
  256. words[1]=0x0;
  257. } else {
  258. words[0]=0xfff0;
  259. words[1]=0x0;
  260. words[2]=0x0;
  261. words[3]=0x0;
  262. }
  263. return return_value;
  264. }
  265. /*
  266. * The floating point formats we support have:
  267. * Bit 15 is sign bit.
  268. * Bits 14:n are excess-whatever exponent.
  269. * Bits n-1:0 (if any) are most significant bits of fraction.
  270. * Bits 15:0 of the next word(s) are the next most significant bits.
  271. *
  272. * So we need: number of bits of exponent, number of bits of
  273. * mantissa.
  274. */
  275. bits_left_in_littlenum = LITTLENUM_NUMBER_OF_BITS;
  276. littlenum_pointer = generic_floating_point_number.leader;
  277. littlenums_left = 1+generic_floating_point_number.leader - generic_floating_point_number.low;
  278. /* Seek (and forget) 1st significant bit */
  279. for (exponent_skippage = 0;! next_bits(1); exponent_skippage ++)
  280. ;
  281. exponent_1 = generic_floating_point_number.exponent + generic_floating_point_number.leader + 1 -
  282. generic_floating_point_number.low;
  283. /* Radix LITTLENUM_RADIX, point just higher than generic_floating_point_number.leader. */
  284. exponent_2 = exponent_1 * LITTLENUM_NUMBER_OF_BITS;
  285. /* Radix 2. */
  286. exponent_3 = exponent_2 - exponent_skippage;
  287. /* Forget leading zeros, forget 1st bit. */
  288. exponent_4 = exponent_3 + ((1 << (exponent_bits - 1)) - 2);
  289. /* Offset exponent. */
  290. lp = words;
  291. /* Word 1. Sign, exponent and perhaps high bits. */
  292. word1 = (generic_floating_point_number.sign == '+') ? 0 : (1<<(LITTLENUM_NUMBER_OF_BITS-1));
  293. /* Assume 2's complement integers. */
  294. if(exponent_4<1 && exponent_4>=-62) {
  295. int prec_bits;
  296. int num_bits;
  297. unget_bits(1);
  298. num_bits= -exponent_4;
  299. prec_bits=LITTLENUM_NUMBER_OF_BITS*precision-(exponent_bits+1+num_bits);
  300. if(precision==X_PRECISION && exponent_bits==15)
  301. prec_bits-=LITTLENUM_NUMBER_OF_BITS+1;
  302. if(num_bits>=LITTLENUM_NUMBER_OF_BITS-exponent_bits) {
  303. /* Bigger than one littlenum */
  304. num_bits-=(LITTLENUM_NUMBER_OF_BITS-1)-exponent_bits;
  305. *lp++=word1;
  306. if(num_bits+exponent_bits+1>=precision*LITTLENUM_NUMBER_OF_BITS) {
  307. /* Exponent overflow */
  308. make_invalid_floating_point_number(words);
  309. return return_value;
  310. }
  311. if(precision==X_PRECISION && exponent_bits==15) {
  312. *lp++=0;
  313. *lp++=0;
  314. num_bits-=LITTLENUM_NUMBER_OF_BITS-1;
  315. }
  316. while(num_bits>=LITTLENUM_NUMBER_OF_BITS) {
  317. num_bits-=LITTLENUM_NUMBER_OF_BITS;
  318. *lp++=0;
  319. }
  320. if(num_bits)
  321. *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS-(num_bits));
  322. } else {
  323. if(precision==X_PRECISION && exponent_bits==15) {
  324. *lp++=word1;
  325. *lp++=0;
  326. if(num_bits==LITTLENUM_NUMBER_OF_BITS) {
  327. *lp++=0;
  328. *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS-1);
  329. } else if(num_bits==LITTLENUM_NUMBER_OF_BITS-1)
  330. *lp++=0;
  331. else
  332. *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS-1-num_bits);
  333. num_bits=0;
  334. } else {
  335. word1|= next_bits ((LITTLENUM_NUMBER_OF_BITS-1) - (exponent_bits+num_bits));
  336. *lp++=word1;
  337. }
  338. }
  339. while(lp<words+precision)
  340. *lp++=next_bits(LITTLENUM_NUMBER_OF_BITS);
  341. /* Round the mantissa up, but don't change the number */
  342. if(next_bits(1)) {
  343. --lp;
  344. if(prec_bits>LITTLENUM_NUMBER_OF_BITS) {
  345. int n = 0;
  346. int tmp_bits;
  347. n=0;
  348. tmp_bits=prec_bits;
  349. while(tmp_bits>LITTLENUM_NUMBER_OF_BITS) {
  350. if(lp[n]!=(LITTLENUM_TYPE)-1)
  351. break;
  352. --n;
  353. tmp_bits-=LITTLENUM_NUMBER_OF_BITS;
  354. }
  355. if(tmp_bits>LITTLENUM_NUMBER_OF_BITS || (lp[n]&mask[tmp_bits])!=mask[tmp_bits]) {
  356. unsigned long int carry;
  357. for (carry = 1; carry && (lp >= words); lp --) {
  358. carry = * lp + carry;
  359. * lp = carry;
  360. carry >>= LITTLENUM_NUMBER_OF_BITS;
  361. }
  362. }
  363. } else if((*lp&mask[prec_bits])!=mask[prec_bits])
  364. *lp++;
  365. }
  366. return return_value;
  367. } else if (exponent_4 & ~ mask [exponent_bits]) {
  368. /*
  369. * Exponent overflow. Lose immediately.
  370. */
  371. /*
  372. * We leave return_value alone: admit we read the
  373. * number, but return a floating exception
  374. * because we can't encode the number.
  375. */
  376. make_invalid_floating_point_number (words);
  377. return return_value;
  378. } else {
  379. word1 |= (exponent_4 << ((LITTLENUM_NUMBER_OF_BITS-1) - exponent_bits))
  380. | next_bits ((LITTLENUM_NUMBER_OF_BITS-1) - exponent_bits);
  381. }
  382. * lp ++ = word1;
  383. /* X_PRECISION is special: it has 16 bits of zero in the middle,
  384. followed by a 1 bit. */
  385. if(exponent_bits==15 && precision==X_PRECISION) {
  386. *lp++=0;
  387. *lp++= 1<<(LITTLENUM_NUMBER_OF_BITS)|next_bits(LITTLENUM_NUMBER_OF_BITS-1);
  388. }
  389. /* The rest of the words are just mantissa bits. */
  390. while(lp < words + precision)
  391. *lp++ = next_bits (LITTLENUM_NUMBER_OF_BITS);
  392. if (next_bits (1)) {
  393. unsigned long int carry;
  394. /*
  395. * Since the NEXT bit is a 1, round UP the mantissa.
  396. * The cunning design of these hidden-1 floats permits
  397. * us to let the mantissa overflow into the exponent, and
  398. * it 'does the right thing'. However, we lose if the
  399. * highest-order bit of the lowest-order word flips.
  400. * Is that clear?
  401. */
  402. /* #if (sizeof(carry)) < ((sizeof(bits[0]) * BITS_PER_CHAR) + 2)
  403. Please allow at least 1 more bit in carry than is in a LITTLENUM.
  404. We need that extra bit to hold a carry during a LITTLENUM carry
  405. propagation. Another extra bit (kept 0) will assure us that we
  406. don't get a sticky sign bit after shifting right, and that
  407. permits us to propagate the carry without any masking of bits.
  408. #endif */
  409. for (carry = 1, lp --; carry && (lp >= words); lp --) {
  410. carry = * lp + carry;
  411. * lp = carry;
  412. carry >>= LITTLENUM_NUMBER_OF_BITS;
  413. }
  414. if ( (word1 ^ *words) & (1 << (LITTLENUM_NUMBER_OF_BITS - 1)) ) {
  415. /* We leave return_value alone: admit we read the
  416. * number, but return a floating exception
  417. * because we can't encode the number.
  418. */
  419. *words&= ~ (1 << (LITTLENUM_NUMBER_OF_BITS - 1));
  420. /* make_invalid_floating_point_number (words); */
  421. /* return return_value; */
  422. }
  423. }
  424. return (return_value);
  425. }
  426. /* This routine is a real kludge. Someone really should do it better, but
  427. I'm too lazy, and I don't understand this stuff all too well anyway
  428. (JF)
  429. */
  430. void
  431. int_to_gen(x)
  432. long x;
  433. {
  434. char buf[20];
  435. char *bufp;
  436. sprintf(buf,"%ld",x);
  437. bufp= &buf[0];
  438. if(atof_generic(&bufp,".", EXP_CHARS, &generic_floating_point_number))
  439. as_warn("Error converting number to floating point (Exponent overflow?)");
  440. }