1 /*
2 * Small C+ Compiler
3 * Split into parts 3/3/99 djm
4 *
5 * This part deals with the evaluation of a constant
6 */
7
8 #include "ccdefs.h"
9
10 #include <math.h>
11 #include "utlist.h"
12
13 static Type *get_member(Type *tag);
14
15
16 typedef struct elem_s {
17 struct elem_s *next;
18 Kind kind;
19 int written;
20 int litlab;
21 zdouble value;
22 unsigned char fa[MAX_MANTISSA_SIZE+1]; /* The parsed representation */
23 char str[60]; /* A raw string version */
24 } elem_t;
25
26 struct fp_decomposed {
27 uint8_t exponent;
28 uint8_t sign;
29 uint8_t mantissa[MAX_MANTISSA_SIZE + 1];
30 };
31
32 static elem_t *bigconst_queue = NULL;
33
34
35 static int hex(char c);
36 static int pstr(LVALUE *lval);
37 static int tstr(int32_t *val);
38 static int fnumber(LVALUE *val);
39 static int number(LVALUE *lval);
40
41 static void dofloat_ieee(double raw, unsigned char fa[]);
42 static void dofloat_ieee16(double raw, unsigned char fa[]);
43 static void dofloat_z80(double raw, unsigned char fa[]);
44 static void dofloat_mbfs(double raw, unsigned char fa[]);
45 static void dofloat_mbf40(double raw, unsigned char fa[]);
46 static void dofloat_mbf64(double raw, unsigned char fa[]);
47 static void dofloat_am9511(double raw, unsigned char fa[]);
48 static void decompose_float(double raw, struct fp_decomposed *fs);
49
50
51 /* Modified slightly to sort have two pools - one for strings and one
52 * for doubles..
53 */
54
constant(LVALUE * lval)55 int constant(LVALUE* lval)
56 {
57 int32_t val;
58 lval->val_type = KIND_INT;
59 lval->ltype = type_int;
60 lval->is_const = 1; /* assume constant will be found */
61 if (fnumber(lval)) {
62 load_constant(lval);
63 lval->flags = FLAGS_NONE;
64 return (1);
65 } else if (number(lval) || pstr(lval)) {
66 if (lval->val_type == KIND_LONG)
67 vlongconst(lval->const_val);
68 else
69 vconst(lval->const_val);
70 return (1);
71 } else if (tstr(&val)) {
72 lval->const_val = val;
73 lval->is_const = 0; /* string address not constant */
74 lval->ltype = make_pointer(type_char);
75 lval->ptr_type = KIND_CHAR;
76 lval->val_type = KIND_INT;
77 lval->flags = FLAGS_NONE;
78 immedlit(litlab,lval->const_val);
79 nl();
80 return (1);
81 }
82 lval->is_const = 0;
83 return (0);
84 }
85
fnumber(LVALUE * lval)86 int fnumber(LVALUE *lval)
87 {
88 int i,k; /* flag and mask */
89 char minus; /* is if negative! */
90 char* start; /* copy of pointer to starting point */
91 char* s; /* points into source code */
92 char* end;
93 double dval;
94 start = s = line + lptr; /* save starting point */
95 k = 1;
96 minus = 1;
97 while (k) {
98 k = 0;
99 if (*s == '+') {
100 ++s;
101 k = 1;
102 }
103 if (*s == '-') {
104 ++s;
105 k = 1;
106 minus = (-minus);
107 }
108 }
109
110 while (*s == ' ') /* Ignore white space after sign */
111 s++;
112
113 while (numeric(*s))
114 ++s;
115
116 if (*s != '.' && (*s != 'e' && *s != 'f')) { /* Check that it is floating point */
117 s++;
118 return 0;
119 }
120 s++;
121 if ( *s == '+' || *s == '-')
122 ++s;
123 while (numeric(*s))
124 ++s;
125
126 lptr = (s--) - line; /* save ending point */
127 dval = strtod(start, &end);
128 if (end == start)
129 return 0;
130
131
132 lptr = end - line;
133
134 lval->val_type = KIND_DOUBLE;
135 lval->ltype = type_double;
136
137 if ( line[lptr] == 'f' ) {
138 lptr++;
139 if ( line[lptr] == '1' && line[lptr+1] == '6') {
140 lptr+=2;
141 lval->val_type = KIND_FLOAT16;
142 lval->ltype = type_float16;
143 }
144 }
145 for ( i = 0; i < buffer_fps_num; i++ )
146 fprintf(buffer_fps[i], "%.*s", (int)(line+lptr-start), start);
147
148 lval->const_val = dval;
149
150 return (1); /* report success */
151 }
152
153
number(LVALUE * lval)154 int number(LVALUE *lval)
155 {
156 char c;
157 int minus;
158 int64_t k;
159 int isunsigned = 0;
160
161 k = minus = 1;
162 while (k) {
163 k = 0;
164 if (cmatch('+'))
165 k = 1;
166 if (cmatch('-')) {
167 minus = (-minus);
168 k = 1;
169 }
170 }
171 if (ch() == '0' && toupper(nch()) == 'X') {
172 gch();
173 gch();
174 if (hex(ch()) == 0)
175 return (0);
176 while (hex(ch())) {
177 c = inbyte();
178 if (c <= '9')
179 k = (k << 4) + (c - '0');
180 else
181 k = (k << 4) + ((c & 95) - '7');
182 }
183 lval->const_val = k;
184 goto typecheck;
185 }
186 if (ch() == '0' && toupper(nch()) == 'B') {
187 int c;
188 gch();
189 gch();
190 if (ch() != '0' && ch() != '1')
191 return (0);
192 while (ch() == '0' || ch() == '1') {
193 c = inbyte();
194 k = (k << 1) + (c - '0');
195 }
196 lval->const_val = k;
197 goto typecheck;
198 }
199 if (ch() == '0') {
200 gch();
201 while (numeric(ch())) {
202 c = inbyte();
203 if (c < '8')
204 k = k * 8 + (c - '0');
205 }
206 lval->const_val = k;
207 goto typecheck;
208 }
209 if (numeric(ch()) == 0)
210 return (0);
211 while (numeric(ch())) {
212 c = inbyte();
213 k = k * 10 + (c - '0');
214 }
215 if (minus < 0)
216 k = (-k);
217 lval->const_val = k;
218 typecheck:
219 lval->val_type = KIND_CHAR;
220 if ( lval->const_val >= 256 || lval->const_val < -127 ) {
221 lval->val_type = KIND_INT;
222 }
223 if ( lval->const_val >= 65536 || lval->const_val < -32767 ) {
224 lval->val_type = KIND_LONG;
225 }
226 if ( lval->const_val >= UINT32_MAX || lval->const_val < INT32_MIN ) {
227 lval->val_type = KIND_LONGLONG;
228 if ( sizeof(long double) == sizeof(double)) {
229 warningfmt("limited-range", "On this host, 64 bit constants may not be correct\n");
230 }
231 }
232 lval->is_const = 1;
233
234 while (checkws() == 0 && (rcmatch('L') || rcmatch('U') || rcmatch('S') || rcmatch('f'))) {
235 if (cmatch('L')) {
236 lval->val_type = KIND_LONG;
237 if (cmatch('L'))
238 lval->val_type = KIND_LONGLONG;
239 }
240 if (cmatch('U')) {
241 isunsigned = 1;
242 lval->const_val = (uint64_t)k;
243 }
244 if (cmatch('S'))
245 isunsigned = 0;
246 if (amatch("f16")) {
247 lval->val_type = KIND_FLOAT16;
248 lval->ltype = type_float16;
249 }
250 if (cmatch('f')) {
251 lval->val_type = KIND_DOUBLE;
252 lval->ltype = type_double;
253 }
254 }
255 if ( lval->val_type == KIND_LONGLONG ) {
256 if ( isunsigned )
257 lval->ltype = type_ulonglong;
258 else
259 lval->ltype = type_longlong;
260 } else if ( lval->val_type == KIND_LONG ) {
261 if ( isunsigned )
262 lval->ltype = type_ulong;
263 else
264 lval->ltype = type_long;
265 } else {
266 if ( isunsigned )
267 lval->ltype = type_uint;
268 else
269 lval->ltype = type_int;
270 }
271 return (1);
272 }
273
hex(char c)274 int hex(char c)
275 {
276 char c1;
277
278 c1 = toupper(c);
279 return ((c1 >= '0' && c1 <= '9') || (c1 >= 'A' && c1 <= 'F'));
280 }
281
282 /* djm, seems to load up literal address? */
283
address(SYMBOL * ptr)284 void address(SYMBOL* ptr)
285 {
286 immed();
287 outname(ptr->name, dopref(ptr));
288 nl();
289 if ( ptr->ctype->kind == KIND_CPTR ) {
290 const2(0);
291 }
292 }
293
pstr(LVALUE * lval)294 int pstr(LVALUE *lval)
295 {
296 int k;
297
298 lval->val_type = KIND_INT;
299 if ( c_default_unsigned ) {
300 lval->ltype = type_uint;
301 } else {
302 lval->ltype = type_int;
303 }
304 if (cmatch('\'')) {
305 k = 0;
306 while (ch() && ch() != '\'')
307 k = (k & 255) * 256 + litchar();
308 gch();
309 lval->const_val = k;
310 return (1);
311 }
312 return (0);
313 }
314
315 /* Scan in literals within function into temporary buffer and then
316 * check to see if present elsewhere, if so do the merge as for doubles
317 */
318
tstr(int32_t * val)319 int tstr(int32_t* val)
320 {
321 int k = 0;
322
323 if (cmatch('"') == 0)
324 return (0);
325 do {
326 while (ch() != '"') {
327 if (ch() == 0)
328 break;
329 tempq[k] = litchar();
330 k++; /* counter */
331 }
332 gch();
333 } while (cmatch('"'));
334 tempq[k] = 0;
335 k++;
336 return (storeq(k, tempq, val));
337 }
338
339 /*
340 * Messed around with 5/5/99 djm to allow queues to start from 1
341 * internally, but to the asm file show it to start from 0
342 */
343
storeq(int length,unsigned char * queue,int32_t * val)344 int storeq(int length, unsigned char* queue, int32_t* val)
345 {
346 int j, k, len;
347 /* Have stashed it in our temporary queue, we know the length, so lets
348 * get checking to see if one exactly the same has already been placed
349 * in there...
350 */
351 k = length;
352 len = litptr - k; /* Amount of leeway to search through.. */
353 j = 1; /* Literal queue starts from 1 not 0 now
354 * this allows scan for miniprintf to work
355 * correctly
356 */
357 while (len >= j) {
358 if (strncmp((char*)queue, (char*)litq + j, k) == 0) {
359 *val = j - 1;
360 return (1);
361 } /*success!*/
362 j++;
363 }
364 /* If we get here, then dump it in the queue as per normal... */
365 *val = (int32_t)litptr - 1;
366 for (j = 0; j < k; j++) {
367 /* Have to dump it in our special queue here for function literals */
368 if ((litptr + 1) >= FNMAX) {
369 errorfmt("Literal Queue Overflow", 1);
370 }
371 *(litq + litptr) = *(queue + j);
372 litptr++;
373 }
374 return (k);
375 }
376
qstr(double * val)377 int qstr(double *val)
378 {
379 int cnt = 0;
380
381 if (cmatch('"') == 0)
382 return (-1);
383
384 *val = gltptr;
385 do {
386 while (ch() != '"') {
387 if (ch() == 0)
388 break;
389 cnt++;
390 stowlit(litchar(), 1);
391 }
392 gch();
393 } while (cmatch('"') || (cmatch('\\') && cmatch('"')));
394
395 glbq[gltptr++] = 0;
396 return (cnt);
397 }
398
399 /* store integer i of size size bytes in global var literal queue */
stowlit(int value,int size)400 void stowlit(int value, int size)
401 {
402 if ((gltptr + size) >= LITMAX) {
403 errorfmt("Literal Queue Overflow", 1);
404 }
405 putint(value, glbq + gltptr, size);
406 gltptr += size;
407 }
408
409 /* Return current literal char & bump lptr */
litchar()410 unsigned char litchar()
411 {
412 int i, oct;
413
414 if (ch() != '\\')
415 return (gch());
416 if (nch() == 0)
417 return (gch());
418 gch();
419 switch (ch()) {
420 case 'a': /* Bell */
421 gch();
422 return 7;
423 case 'b': /* BS */
424 gch();
425 return 8;
426 case 't': /* HT */
427 gch();
428 return 9;
429 case 'r': /* LF */
430 gch();
431 return c_standard_escapecodes ? 13 : 10;
432 case 'v': /* VT */
433 gch();
434 return 11;
435 case 'f': /* FF */
436 gch();
437 return 12;
438 case 'n': /* CR */
439 gch();
440 return c_standard_escapecodes ? 10 : 13;
441 case '\"': /* " */
442 gch();
443 return 34;
444 case '\'': /* ' */
445 gch();
446 return 39;
447 case '\\': /* / */
448 gch();
449 return '\\';
450 case '\?': /* ? */
451 gch();
452 return '\?';
453 case 'l': /* LF (non standard)*/
454 gch();
455 return 10;
456 case 'e':
457 gch();
458 return 27;
459 }
460
461 if (ch() != 'x' && (ch() < '0' || ch() > '7')) {
462 warningfmt("parser","Unknown escape sequence \\%c", ch());
463 return (gch());
464 }
465 if (ch() == 'x') {
466 gch();
467 oct = 0;
468 i = 2;
469 while (i-- > 0 && hex(ch())) {
470 if (ch() <= '9')
471 oct = (oct << 4) + (gch() - '0');
472 else
473 oct = (oct << 4) + ((gch() & 95) - '7');
474 }
475 if (isxdigit(ch())) {
476 warningfmt("parser","Hex escape sequence out of range");
477 }
478 return ((char)oct);
479 }
480
481 i = 3;
482 oct = 0;
483 while (i-- > 0 && ch() >= '0' && ch() <= '7')
484 oct = (oct << 3) + gch() - '0';
485 if (i == 2)
486 return (gch());
487 else {
488 return ((char)oct);
489 }
490 }
491
492 /* Perform an offsetof(structure, member) */
offset_of(LVALUE * lval)493 void offset_of(LVALUE *lval)
494 {
495 char struct_name[NAMESIZE];
496 char memb_name[NAMESIZE];
497 char foundit = 0;
498
499 memb_name[0] = struct_name[0] = 0;
500 needchar('(');
501 if ( symname(struct_name) ) {
502 needchar(',');
503 if ( symname(memb_name) ) {
504 Type* tag = find_tag(struct_name);
505
506 /* Consider typedefs */
507 if ( tag == NULL ) {
508 SYMBOL *ptr;
509
510 if (((ptr = findloc(struct_name)) != NULL) || ((ptr = findstc(struct_name)) != NULL) || ((ptr = findglb(struct_name)) != NULL)) {
511 if ( ispointer(ptr->ctype) && ptr->ctype->ptr->kind == KIND_STRUCT ) {
512 tag = ptr->ctype->ptr->tag;
513 } else if ( ptr->ctype->kind == KIND_STRUCT ) {
514 tag = ptr->ctype->tag;
515 } else {
516 printf("%d\n",ptr->type);
517 }
518 }
519 }
520 if ( tag != NULL ) {
521 Type *member = find_tag_field(tag, memb_name);
522
523 if ( member != NULL ) {
524 foundit = 1;
525 lval->const_val = member->offset;
526 }
527 }
528 }
529 }
530 needchar(')');
531 if ( foundit ) {
532 lval->is_const = 1;
533 lval->ltype = type_int;
534 lval->val_type = KIND_INT;
535 vconst(lval->const_val);
536 } else {
537 errorfmt("Cannot evaluate __builtin_offsetof(%s,%s)", 1, strlen(struct_name) ? struct_name : "<unknown>", strlen(memb_name) ? memb_name : "<unknown>");
538 }
539
540
541 }
542
543 /* Perform a sizeof (works on variables as well */
size_of(LVALUE * lval)544 void size_of(LVALUE* lval)
545 {
546 char sname[NAMESIZE];
547 int length;
548 Type *type;
549 SYMBOL *ptr;
550 int deref = 0;
551 int brackets = 0;
552
553 if ( rcmatch('(')) {
554 brackets = 1;
555 needchar('(');
556 }
557 while ( cmatch('*') ) {
558 deref++;
559 }
560 lval->ltype = type_int;
561
562 if ( (type = parse_expr_type()) != NULL ) {
563 if ( deref && type->kind != KIND_PTR ) {
564 UT_string *str;
565 utstring_new(str);
566 type_describe(type, str);
567 errorfmt("sizeof expects a pointer but got %s", 1, utstring_body(str) );
568 utstring_free(str);
569 lval->const_val = 2;
570 lval->is_const = 1;
571 return;
572 }
573 while ( deref && type ) {
574 Type *next = type->ptr;
575 type = next;
576 deref--;
577 }
578 if ( type == NULL ) {
579 lval->const_val = 2;
580 lval->is_const = 1;
581 errorfmt("Cannot dereference far enough, assuming size of 2",1);
582 } else {
583 lval->const_val = type->size;
584 }
585 } else if (cmatch('"')) { /* Check size of string */
586 length = 1; /* Always at least one */
587 do
588 {
589 while (!cmatch('"')) {
590 length++;
591 litchar();
592 };
593 /* Keep going for "concatenated" "strings" */
594 if (!cmatch('"')) {
595 break;
596 }
597 /* But correct the opening quotes */
598 length--;
599 } while (1);
600 lval->const_val = length;
601 if ( deref )
602 lval->const_val = 1;
603 } else if (symname(sname)) { /* Size of an object */
604 Type *type;
605 if (((ptr = findloc(sname)) != NULL) || ((ptr = findstc(sname)) != NULL) || ((ptr = findglb(sname)) != NULL)) {
606 type = ptr->ctype;
607 lval->const_val = type->size;
608
609 if (type->kind != KIND_FUNC && ptr->ident != ID_MACRO) {
610 if ( type->kind == KIND_PTR && type->ptr->kind == KIND_STRUCT ) {
611 type = type->ptr;
612 }
613 if (type->kind != KIND_STRUCT ) {
614 } else {
615 Type *mptr;
616
617 /* We're a member of a structure */
618 do {
619 if ( (mptr = get_member(type->kind == KIND_STRUCT ? type->tag : type->ptr->tag) ) != NULL ) {
620 type = mptr;
621 if ( (mptr->kind == KIND_PTR || mptr->kind == KIND_CPTR) && deref ) {
622 // Do nothing
623 } else {
624 // tag_sym->size = numner of elements
625 lval->const_val = mptr->size;
626 }
627 } else {
628 lval->const_val = type->size;
629 }
630 } while ( mptr && ( (mptr->kind == KIND_STRUCT && rcmatch('.')) ||
631 ( ispointer(mptr) && mptr->ptr->kind == KIND_STRUCT && rmatch2("->"))) );
632 }
633 /* Check for index operator on array */
634 if (type->kind == KIND_ARRAY ) {
635 if (rcmatch('[')) {
636 double val;
637 Kind valtype;
638 needchar('[');
639 constexpr(&val, &valtype, 1);
640 needchar(']');
641 deref++;
642 lval->const_val = type->size / type->len;
643 }
644 }
645 while ( deref && type ) {
646 lval->const_val = type->size;
647 type = type->ptr;
648 if ( type ) {
649 lval->const_val = type->size;
650 }
651 deref--;
652 }
653 } else {
654 lval->const_val = 2;
655 }
656 } else {
657 errorfmt("Unknown symbol: %s", 1, sname);
658 }
659 }
660 if ( brackets )
661 needchar(')');
662 lval->is_const = 1;
663 lval->val_type = KIND_INT;
664 vconst(lval->const_val);
665 }
666
get_member(Type * tag)667 static Type *get_member(Type *tag)
668 {
669 char sname[NAMESIZE];
670 Type *member;;
671
672 if (cmatch('.') == NO && match("->") == NO)
673 return NULL;
674
675 if (symname(sname) && (member = find_tag_field(tag, sname))) {
676 return member;
677 }
678 errorfmt("Unknown member: %s", 1, sname);
679 return NULL;
680 }
681
682
683
684
dofloat(enum maths_mode mode,double raw,unsigned char fa[])685 void dofloat(enum maths_mode mode,double raw, unsigned char fa[])
686 {
687 switch ( mode ) {
688 case MATHS_IEEE:
689 dofloat_ieee(raw, fa);
690 break;
691 case MATHS_MBFS:
692 dofloat_mbfs(raw, fa);
693 break;
694 case MATHS_MBF40:
695 dofloat_mbf40(raw, fa);
696 break;
697 case MATHS_MBF64:
698 dofloat_mbf64(raw, fa);
699 break;
700 case MATHS_IEEE16:
701 dofloat_ieee16(raw, fa);
702 break;
703 case MATHS_AM9511:
704 dofloat_am9511(raw, fa);
705 break;
706 default:
707 dofloat_z80(raw, fa);
708 break;
709 }
710 }
711
pack32bit_float(uint32_t val,unsigned char fa[])712 static void pack32bit_float(uint32_t val, unsigned char fa[])
713 {
714 fa[0] = val & 0xff;
715 fa[1] = (val >> 8) & 0xff;
716 fa[2] = (val >> 16) & 0xff;
717 fa[3] = (val >> 24) & 0xff;
718 }
719
dofloat_ieee(double raw,unsigned char fa[])720 static void dofloat_ieee(double raw, unsigned char fa[])
721 {
722 if ( isnan(raw)) {
723 // quiet nan: 7FC00000
724 // signalling nan: 7F800001
725 pack32bit_float(0x7fc00000, fa);
726 fa[0] = 0x00;
727 fa[1] = 0x00;
728 fa[2] = 0xc0;
729 fa[3] = 0x7f;
730 } else if ( isinf(raw) && raw > 0 ) {
731 // positive infinity: 7F800000
732 pack32bit_float(0x7f800000, fa);
733 fa[0] = 0x00;
734 fa[1] = 0x00;
735 fa[2] = 0x80;
736 fa[3] = 0x7f;
737 } else if ( isinf(raw) && raw < 0 ) {
738 // negative infinity: FF800000
739 pack32bit_float(0xff800000, fa);
740 } else {
741 struct fp_decomposed fs = {0};
742 uint32_t fp_value = 0;
743
744 decompose_float(raw, &fs);
745
746 // Bundle up mantissa
747 fp_value = ( ( (uint32_t)fs.mantissa[4]) | ( ((uint32_t)fs.mantissa[5]) << 8) | (((uint32_t)fs.mantissa[6]) << 16)) & 0x007fffff;
748
749 // And now the exponent
750 fp_value |= (((uint32_t)fs.exponent) << 23);
751
752 // And the sign bit
753 fp_value |= fs.sign ? 0x80000000 : 0x00000000;
754 pack32bit_float(fp_value, fa);
755 }
756 }
757
dofloat_ieee16(double raw,unsigned char fa[])758 static void dofloat_ieee16(double raw, unsigned char fa[])
759 {
760 if ( isnan(raw)) {
761 fa[0] = 0xff;
762 fa[1] = 0xff;
763 } else if ( isinf(raw) && raw > 0 ) {
764 // positive infinity: 7c00
765 fa[0] = 0x00;
766 fa[1] = 0x7c;
767 } else if ( isinf(raw) && raw < 0 ) {
768 // positive infinity: 7c00
769 fa[0] = 0x00;
770 fa[1] = 0xfc;
771 } else {
772 struct fp_decomposed fs = {0};
773 uint32_t fp_value = 0;
774 int saved_exp = c_fp_exponent_bias;
775 int saved_mant = c_fp_mantissa_bytes;
776
777 c_fp_exponent_bias = 14;
778 c_fp_mantissa_bytes = 2;
779 decompose_float(raw, &fs);
780
781 c_fp_exponent_bias = saved_exp;
782 c_fp_mantissa_bytes = saved_mant;
783
784
785
786 // Bundle up mantissa - it's only 10 bits
787 fp_value = ((((uint32_t)fs.mantissa[6]) << 3) | ((((uint32_t)fs.mantissa[5]) >> 5 ) & 0x07) ) & 0x3ff ;
788
789 // And now the exponent
790 fp_value |= (((uint32_t)fs.exponent) << 10) & 0x7fc0;
791
792 // And the sign bit
793 fp_value |= fs.sign ? 0x8000 : 0x0000;
794 fa[0] = fp_value & 0xff;
795 fa[1] = (fp_value & 0xff00) >> 8;
796 }
797 }
798
dofloat_mbfs(double raw,unsigned char fa[])799 static void dofloat_mbfs(double raw, unsigned char fa[])
800 {
801 struct fp_decomposed fs = {0};
802 uint32_t fp_value = 0;
803
804 decompose_float(raw, &fs);
805
806 // Bundle up mantissa
807 fp_value = ( ( (uint32_t)fs.mantissa[4]) | ( ((uint32_t)fs.mantissa[5]) << 8) | (((uint32_t)fs.mantissa[6]) << 16)) & 0x007fffff;
808
809 // And now the exponent
810 fp_value |= (((uint32_t)fs.exponent) << 24);
811
812 // And the sign bit
813 fp_value |= fs.sign ? 0x00800000 : 0x00000000;
814 pack32bit_float(fp_value, fa);
815 }
816
dofloat_am9511(double raw,unsigned char fa[])817 static void dofloat_am9511(double raw, unsigned char fa[])
818 {
819 struct fp_decomposed fs = {0};
820 uint32_t fp_value = 0;
821
822 if ( raw != 0.0 ) {
823 decompose_float(raw, &fs);
824
825 // Bundle up mantissa
826 fp_value = (((uint32_t)fs.mantissa[4]) | ( ((uint32_t)fs.mantissa[5]) << 8) | (((uint32_t)fs.mantissa[6]) << 16)) | 0x00800000;
827
828 // And now the exponent
829 fp_value |= ((((uint32_t)fs.exponent) << 24) & 0x7f000000);
830
831 // And the sign bit
832 fp_value |= fs.sign ? 0x80000000 : 0x00000000;
833 }
834 pack32bit_float(fp_value, fa);
835 }
836
837
dofloat_mbf64(double raw,unsigned char fa[])838 static void dofloat_mbf64(double raw, unsigned char fa[])
839 {
840 struct fp_decomposed fs = {0};
841
842 decompose_float(raw, &fs);
843
844 memcpy(fa, fs.mantissa, 7);
845 fa[6] |= fs.sign ? 0x80 : 00;
846 fa[7] = fs.exponent;
847 }
848
849
dofloat_mbf40(double raw,unsigned char fa[])850 static void dofloat_mbf40(double raw, unsigned char fa[])
851 {
852 struct fp_decomposed fs = {0};
853
854 decompose_float(raw, &fs);
855
856 memcpy(fa, fs.mantissa + 3, 4);
857 fa[3] |= fs.sign ? 0x80 : 00;
858 fa[4] = fs.exponent;
859 }
860
dofloat_z80(double raw,unsigned char fa[])861 static void dofloat_z80(double raw, unsigned char fa[])
862 {
863 struct fp_decomposed fs = {0};
864 int offs = MAX_MANTISSA_SIZE - c_fp_mantissa_bytes;
865 int i;
866
867 decompose_float(raw, &fs);
868
869
870 for ( i = offs; i < MAX_MANTISSA_SIZE ; i++ ) {
871 fa[i - offs + c_fp_fudge_offset] = fs.mantissa[i];
872 }
873 fa[i - offs -1 + c_fp_fudge_offset] |= fs.sign ? 0x80 : 0;
874 fa[i - offs + c_fp_fudge_offset] = fs.exponent;
875 }
876
877
decompose_float(double raw,struct fp_decomposed * fs)878 static void decompose_float(double raw, struct fp_decomposed *fs)
879 {
880 double norm;
881 double x = fabs(raw);
882 double exp = log(x) / log(2);
883 int i;
884 int mant_bytes = c_fp_mantissa_bytes;
885 int exp_bias = c_fp_exponent_bias;
886
887 fs->sign = 0;
888 fs->exponent = 0;
889
890 for ( i = 0; i < MAX_MANTISSA_SIZE; i++ ) {
891 fs->mantissa[i] = 0;
892 }
893
894 if (mant_bytes > MAX_MANTISSA_SIZE ) {
895 mant_bytes = MAX_MANTISSA_SIZE;
896 }
897
898 if (x == 0.0) {
899 memset(fs->mantissa, 0, MAX_MANTISSA_SIZE + 1);
900 return;
901 }
902
903 if (floor(exp) == ceil(exp)) {
904 exp = ceil(exp) + 1;
905 } else {
906 exp = ceil(exp);
907 }
908
909 norm = x / pow(2, exp);
910
911 fs->exponent = (int)exp + exp_bias;
912 for (i = 0; i < (mant_bytes * 2) + 1; i++) {
913 double mult = norm * 16.;
914 double res = floor(mult);
915 unsigned char bit = res;
916
917 if (i == 0 && raw > 0)
918 bit -= 8;
919 if (i == mant_bytes * 2) {
920 if (bit > 7) {
921 int carry = 1;
922 for (i = MAX_MANTISSA_SIZE - mant_bytes; i < MAX_MANTISSA_SIZE; i++) {
923 int res = fs->mantissa[i] + carry;
924
925 fs->mantissa[i] = res % 256;
926 carry = res / 256;
927 }
928 }
929 break;
930 }
931 if (i % 2 == 0) {
932 fs->mantissa[(MAX_MANTISSA_SIZE-1) - i / 2] = (bit << 4);
933 } else {
934 fs->mantissa[(MAX_MANTISSA_SIZE-1) - i / 2] |= (bit & 0x0f);
935 }
936 norm = mult - res;
937 }
938 if ( raw < 0 ) {
939 fs->sign = 1;
940 }
941 }
942
943
get_elem_for_fa(unsigned char fa[],double value)944 elem_t *get_elem_for_fa(unsigned char fa[], double value)
945 {
946 elem_t *elem;
947
948 LL_FOREACH(bigconst_queue, elem ) {
949 if ( elem->kind == KIND_DOUBLE && memcmp(elem->fa, fa, MAX_MANTISSA_SIZE) == 0 ) {
950 return elem;
951 }
952 }
953 elem = MALLOC(sizeof(*elem));
954 elem->kind = KIND_DOUBLE;
955 elem->litlab = getlabel();
956 elem->value = value;
957 elem->written = 0;
958 memcpy(elem->fa, fa, MAX_MANTISSA_SIZE+1);
959 LL_APPEND(bigconst_queue, elem);
960 return elem;
961 }
962
indicate_constant_written(int litlab)963 void indicate_constant_written(int litlab)
964 {
965 elem_t *elem;
966
967 LL_FOREACH(bigconst_queue, elem ) {
968 if ( elem->litlab == litlab ) {
969 elem->written = 1;
970 }
971 }
972 }
973
get_elem_for_buf(char * str,double value)974 elem_t *get_elem_for_buf(char *str, double value)
975 {
976 elem_t *elem;
977
978 LL_FOREACH(bigconst_queue, elem ) {
979 if ( elem->kind == KIND_DOUBLE && strcmp(elem->str, str) == 0 ) {
980 return elem;
981 }
982 }
983 elem = MALLOC(sizeof(*elem));
984 elem->kind = KIND_DOUBLE;
985 elem->litlab = getlabel();
986 elem->value = value;
987 elem->written = 0;
988 strcpy(elem->str,str);
989 LL_APPEND(bigconst_queue, elem);
990 return elem;
991 }
992
993
get_elem_for_llong(char buf[8])994 elem_t *get_elem_for_llong(char buf[8])
995 {
996 elem_t *elem;
997
998 LL_FOREACH(bigconst_queue, elem ) {
999 if ( elem->kind == KIND_LONGLONG && memcmp(elem->fa, buf, 8) == 0 ) {
1000 return elem;
1001 }
1002 }
1003 elem = MALLOC(sizeof(*elem));
1004 elem->kind = KIND_LONGLONG;
1005 elem->litlab = getlabel();
1006 elem->written = 0;
1007 memcpy(elem->fa, buf, 8);
1008 LL_APPEND(bigconst_queue, elem);
1009 return elem;
1010 }
1011
1012
1013
write_constant_queue(void)1014 void write_constant_queue(void)
1015 {
1016 elem_t *elem;
1017
1018 LL_FOREACH(bigconst_queue, elem ) {
1019 if ( elem->written ) {
1020 gen_switch_section(c_rodata_section);
1021 prefix();
1022 queuelabel(elem->litlab);
1023 col();
1024 nl();
1025 if ( elem->kind == KIND_DOUBLE) {
1026 if ( c_double_strings ) {
1027 defmesg(); outstr(elem->str); outstr("\"\n");
1028 defbyte(); outdec(0); nl();
1029 } else {
1030 char buf[128];
1031 int i, offs;
1032
1033 for ( i = 0, offs = 0; i < c_fp_size; i++) {
1034 offs += snprintf(buf + offs, sizeof(buf) - offs,"%s0x%02x", i != 0 ? "," : "", elem->fa[i]);
1035 }
1036 //outfmt("\t;%lf ref: %d written: %d\n",elem->value,elem->refcount, elem->written);
1037 outfmt("\t;%Lf\n",elem->value);
1038 outfmt("\tdefb\t%s\n", buf);
1039 }
1040 } else {
1041 char buf[128];
1042 int i, offs;
1043 for ( i = 0, offs = 0; i < 8; i++) {
1044 offs += snprintf(buf + offs, sizeof(buf) - offs,"%s0x%02x", i != 0 ? "," : "", elem->fa[i]);
1045 }
1046 outfmt("\tdefb\t%s\n", buf);
1047 }
1048 }
1049 }
1050 nl();
1051 }
1052
load_llong_into_acc(zdouble val)1053 void load_llong_into_acc(zdouble val)
1054 {
1055 uint64_t v,l;
1056 char buf[8];
1057 elem_t *elem;
1058
1059 v = val;
1060
1061
1062 l = v & 0xffffffff;
1063 buf[0] = (l % 65536) % 256;
1064 buf[1] = (l % 65536) / 256;
1065 buf[2] = (l / 65536) % 256;
1066 buf[3] = (l / 65536) / 256;
1067 l = (v >> 32) & 0xffffffff;
1068 buf[4] = (l % 65536) % 256;
1069 buf[5] = (l % 65536) / 256;
1070 buf[6] = (l / 65536) % 256;
1071 buf[7] = (l / 65536) / 256;
1072
1073 elem = get_elem_for_llong(buf);
1074 immedlit(elem->litlab,0);
1075 nl();
1076 callrts("l_i64_load");
1077 }
1078
1079
load_double_into_fa(LVALUE * lval)1080 void load_double_into_fa(LVALUE *lval)
1081 {
1082 unsigned char fa[MAX_MANTISSA_SIZE+1] = {0};
1083 elem_t *elem;
1084 memset(fa, 0, sizeof(fa));
1085
1086 if ( c_double_strings ) {
1087 char buf[40];
1088 snprintf(buf, sizeof(buf), "%Lf", lval->const_val);
1089 elem = get_elem_for_buf(buf, lval->const_val);
1090 immedlit(elem->litlab,0);
1091 nl();
1092 callrts("__atof2");
1093 WriteDefined("math_atof", 1);
1094 } else {
1095 dofloat(c_maths_mode,lval->const_val, fa);
1096 if ( lval->val_type == KIND_FLOAT16 ) {
1097 dofloat_ieee16(lval->const_val, fa);
1098 vconst(fa[1] << 8 | fa[0]);
1099 } else if ( c_fp_size == 4 ) {
1100 vconst(fa[1] << 8 | fa[0]);
1101 const2(fa[3] << 8 | fa[2]);
1102 } else {
1103 elem = get_elem_for_fa(fa,lval->const_val);
1104 immedlit(elem->litlab,0);
1105 nl();
1106 callrts("dload");
1107 }
1108 }
1109 }
1110