Pristine Ack-5.5
[Ack-5.5.git] / lang / cem / cemcom / arith.c
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: arith.c,v 3.27 1994/06/24 12:01:56 ceriel Exp $ */
6 /*      A R I T H M E T I C   C O N V E R S I O N S      */
7
8 /*      This file contains the routines for the various conversions that
9         may befall operands in C. It is structurally a mess, but I haven't
10         decided yet whether I can't find the right structure or the
11         semantics of C is a mess.
12 */
13
14 #include        <alloc.h>
15 #include        "lint.h"
16 #include        "nofloat.h"
17 #include        "nobitfield.h"
18 #include        "idf.h"
19 #include        "arith.h"
20 #include        "type.h"
21 #include        "label.h"
22 #include        "expr.h"
23 #include        "Lpars.h"
24 #include        "field.h"
25 #include        "mes.h"
26 #include        "noRoption.h"
27
28 extern char *symbol2str();
29 extern char options[];
30
31 arithbalance(e1p, oper, e2p)    /* RM 6.6 */
32         register struct expr **e1p, **e2p;
33         int oper;
34 {
35         /*      The expressions *e1p and *e2p are balanced to be operands
36                 of the arithmetic operator oper.
37         */
38         register int t1, t2, u1, u2;
39
40         t1 = any2arith(e1p, oper);
41         t2 = any2arith(e2p, oper);
42
43         /* Now t1 and t2 are either INT or LONG or DOUBLE */
44 #ifndef NOFLOAT
45         if (t1 == DOUBLE) {
46                 if (t2 != DOUBLE)
47                         int2float(e2p, double_type);
48                 return;
49         }
50         if (t2 == DOUBLE) {
51                 if (t1 != DOUBLE)
52                         int2float(e1p, double_type);
53                 return;
54         }
55 #endif /* NOFLOAT */
56
57         /* Now they are INT or LONG */
58         u1 = (*e1p)->ex_type->tp_unsigned;
59         u2 = (*e2p)->ex_type->tp_unsigned;
60
61         /* if either is long, the other will be */
62         if (t1 == LONG && t2 != LONG)
63                 t2 = int2int(e2p, u2 ? ulong_type : long_type);
64         else
65         if (t2 == LONG && t1 != LONG)
66                 t1 = int2int(e1p, u1 ? ulong_type : long_type);
67
68         /* if either is unsigned, the other will be     */
69         if (u1 && !u2)
70                 t2 = int2int(e2p, (t1 == LONG) ? ulong_type : uint_type);
71         else
72         if (!u1 && u2)
73                 t1 = int2int(e1p, (t2 == LONG) ? ulong_type : uint_type);
74 }
75
76 relbalance(e1p, oper, e2p)
77         register struct expr **e1p, **e2p;
78 {
79         /*      The expressions *e1p and *e2p are balanced to be operands
80                 of the relational operator oper.
81         */
82         if ((*e1p)->ex_type->tp_fund == FUNCTION)
83                 function2pointer(*e1p);
84         if ((*e2p)->ex_type->tp_fund == FUNCTION)
85                 function2pointer(*e2p);
86         if ((*e1p)->ex_type->tp_fund == POINTER)
87                 ch76pointer(e2p, oper, (*e1p)->ex_type);
88         else
89         if ((*e2p)->ex_type->tp_fund == POINTER)
90                 ch76pointer(e1p, oper, (*e2p)->ex_type);
91         else
92         if (    (*e1p)->ex_type == (*e2p)->ex_type &&
93                 (*e1p)->ex_type->tp_fund == ENUM
94         )
95                 {}
96         else
97                 arithbalance(e1p, oper, e2p);
98 }
99
100 ch76pointer(expp, oper, tp)
101         struct expr **expp;
102         register struct type *tp;
103 {
104         /*      Checks whether *expp may be compared to tp using oper,
105                 as described in chapter 7.6 and 7.7.
106                 tp is known to be a pointer.
107         */
108         register struct expr *exp = *expp;
109
110         if (exp->ex_type->tp_fund == POINTER)   {
111                 if (exp->ex_type != tp)
112                         ch7cast(expp, oper, tp);
113         }
114         else
115         if (is_integral_type(exp->ex_type)) {
116                 if (    (oper != EQUAL && oper != NOTEQUAL && oper != ':') ||
117                         (!is_cp_cst(exp) || exp->VL_VALUE != 0)
118                 ) {     /* ch 7.6, ch 7.7 */
119                         expr_warning(exp, "%s on %s and pointer",
120                                           symbol2str(oper),
121                                           symbol2str(exp->ex_type->tp_fund)
122                                 );
123                 }
124                 ch7cast(expp, CAST, tp);
125         }
126         else    {
127                 expr_error(exp, "%s on %s and pointer",
128                                 symbol2str(oper),
129                                 symbol2str(exp->ex_type->tp_fund)
130                         );
131                 ch7cast(expp, oper, tp);
132         }
133 }
134
135 int
136 any2arith(expp, oper)
137         register struct expr **expp;
138         register int oper;
139 {
140         /*      Turns any expression into int_type, long_type or
141                 double_type.
142         */
143         int fund;
144
145         switch (fund = (*expp)->ex_type->tp_fund)       {
146         case CHAR:
147         case SHORT:
148                 int2int(expp,
149                         (*expp)->ex_type->tp_unsigned ? uint_type : int_type);
150                 break;
151         case INT:
152         case LONG:
153                 break;
154         case ENUM:
155                 /* test the admissibility of the operator */
156                 if (    is_test_op(oper) || oper == '=' || oper == PARCOMMA ||
157                         oper == ',' || oper == ':'
158                 )       {
159                         /* allowed by K & R */
160                 }
161                 else
162 #ifndef NOROPTION
163                 if (!options['R'])      {
164                         /* allowed by us */
165                 }
166                 else
167                         expr_warning(*expp, "%s on enum", symbol2str(oper));
168 #endif /* NOROPTION */
169 #ifndef LINT
170                 int2int(expp, int_type);
171 #endif  /* LINT */
172                 break;
173 #ifndef NOFLOAT
174         case FLOAT:
175                 float2float(expp, double_type);
176                 break;
177         case DOUBLE:
178                 break;
179 #endif  /* NOFLOAT */
180 #ifndef NOBITFIELD
181         case FIELD:
182                 field2arith(expp);
183                 break;
184 #endif /* NOBITFIELD */
185         default:
186                 expr_error(*expp, "operator %s on non-numerical operand (%s)",
187                         symbol2str(oper), symbol2str(fund));
188         case ERRONEOUS:
189                 erroneous2int(expp);
190                 break;
191         }
192
193         return (*expp)->ex_type->tp_fund;
194 }
195
196 erroneous2int(expp)
197         struct expr **expp;
198 {
199         /*      the (erroneous) expression *expp is replaced by an
200                 int expression
201         */
202         register struct expr *exp = *expp;
203         int flags = exp->ex_flags;
204         
205         free_expression(exp);
206         exp = intexpr((arith)0, INT);
207         exp->ex_flags = (flags | EX_ERROR);
208         *expp = exp;
209 }
210
211 struct expr *
212 arith2arith(tp, oper, expr)
213         struct type *tp;
214         int oper;
215         register struct expr *expr;
216 {
217         /*      arith2arith constructs a new expression containing a
218                 run-time conversion between some arithmetic types.
219         */
220         register struct expr *new = new_expr();
221         
222         new->ex_file = expr->ex_file;
223         new->ex_line = expr->ex_line;
224         new->ex_type = tp;
225         new->ex_class = Type;
226         return new_oper(tp, new, oper, expr);
227 }
228
229 int
230 int2int(expp, tp)
231         struct expr **expp;
232         register struct type *tp;
233 {
234         /*      The expression *expp, which is of some integral type, is
235                 converted to the integral type tp.
236         */
237         register struct expr *exp = *expp;
238         
239         if (is_cp_cst(exp))     {
240                 register struct type *tp1 = exp->ex_type;
241
242                 exp->ex_type = tp;
243                 if (! tp1->tp_unsigned && tp->tp_unsigned) {
244                         /*      Avoid "unreal" overflow warnings, such as
245                                 caused by f.i.:
246                                         unsigned int x = ~0;
247                                         unsigned int y = -1;
248                         */
249                         extern long full_mask[];
250                         long remainder = exp->VL_VALUE &
251                                                 ~full_mask[(int)(tp->tp_size)];
252
253                         if (remainder == 0 ||
254                             remainder == ~full_mask[(int)(tp->tp_size)]) {
255                                 exp->VL_VALUE &= ~remainder;
256                         }
257                 }
258                 cut_size(exp);
259         }
260         else    {
261                 exp = arith2arith(tp, INT2INT, exp);
262         }
263         *expp = exp;
264         return exp->ex_type->tp_fund;
265 }
266
267 #ifndef NOFLOAT
268 int2float(expp, tp)
269         register struct expr **expp;
270         struct type *tp;
271 {
272         /*      The expression *expp, which is of some integral type, is
273                 converted to the floating type tp.
274         */
275         register struct expr *exp = *expp;
276         char buf[32];
277         
278         fp_used = 1;
279         if (is_cp_cst(exp)) {
280                 *expp = new_expr();
281                 **expp = *exp;
282                 sprint(buf+1, "%ld", (long)(exp->VL_VALUE));
283                 buf[0] = '-';
284                 exp = *expp;
285                 exp->ex_type = tp;
286                 exp->ex_class = Float;
287                 exp->FL_VALUE = Salloc(buf, (unsigned)strlen(buf)+2) + 1;
288                 exp->FL_DATLAB = 0;
289         }
290         else    *expp = arith2arith(tp, INT2FLOAT, *expp);
291 }
292
293 float2int(expp, tp)
294         struct expr **expp;
295         struct type *tp;
296 {
297         /*      The expression *expp, which is of some floating type, is
298                 converted to the integral type tp.
299         */
300         
301         fp_used = 1;
302         *expp = arith2arith(tp, FLOAT2INT, *expp);
303 }
304
305 float2float(expp, tp)
306         register struct expr **expp;
307         struct type *tp;
308 {
309         /*      The expression *expp, which is of some floating type, is
310                 converted to the floating type tp.
311                 There is no need for an explicit conversion operator
312                 if the expression is a constant.
313         */
314         
315         fp_used = 1;
316         if (is_fp_cst(*expp))
317                 (*expp)->ex_type = tp;
318         else
319                 *expp = arith2arith(tp, FLOAT2FLOAT, *expp);
320 }
321 #endif /* NOFLOAT */
322
323 array2pointer(exp)
324         register struct expr *exp;
325 {
326         /*      The expression, which must be an array, is converted
327                 to a pointer.
328         */
329         exp->ex_type = construct_type(POINTER, exp->ex_type->tp_up, (arith)0);
330 }
331
332 function2pointer(exp)
333         register struct expr *exp;
334 {
335         /*      The expression, which must be a function, is converted
336                 to a pointer to the function.
337         */
338         exp->ex_type = construct_type(POINTER, exp->ex_type, (arith)0);
339 }
340
341 string2pointer(ex)
342         register struct expr *ex;
343 {
344         /*      The expression, which must be a string constant, is converted
345                 to a pointer to the string-containing area.
346         */
347         label lbl = data_label();
348
349         code_string(ex->SG_VALUE, ex->SG_LEN, lbl);
350         ex->ex_class = Value;
351         ex->VL_CLASS = Label;
352         ex->VL_LBL = lbl;
353         ex->VL_VALUE = (arith)0;
354 }
355
356 opnd2integral(expp, oper)
357         register struct expr **expp;
358         int oper;
359 {
360         register int fund = (*expp)->ex_type->tp_fund;
361
362         if (fund != INT && fund != LONG)        {
363                 expr_error(*expp, "%s operand to %s",
364                                 symbol2str(fund), symbol2str(oper));
365                 erroneous2int(expp);
366                 /* fund = INT; */
367         }
368 }
369
370 opnd2logical(expp, oper)
371         register struct expr **expp;
372         int oper;
373 {
374         int fund = (*expp)->ex_type->tp_fund;
375
376         if (fund == FUNCTION || fund == ARRAY) {
377                 expr_warning(*expp, "%s operand to %s",
378                         symbol2str(fund),
379                         symbol2str(oper));
380                 if (fund == FUNCTION) {
381                         function2pointer(*expp);
382                 }
383                 else    array2pointer(*expp);
384         }
385 #ifndef NOBITFIELD
386         else
387         if (fund == FIELD)
388                 field2arith(expp);
389 #endif /* NOBITFIELD */
390         switch (fund = (*expp)->ex_type->tp_fund) {
391         case CHAR:
392         case SHORT:
393         case INT:
394         case LONG:
395         case ENUM:
396         case POINTER:
397 #ifndef NOFLOAT
398         case FLOAT:
399         case DOUBLE:
400 #endif /* NOFLOAT */
401                 break;
402         default:
403                 expr_error(*expp, "%s operand to %s",
404                         symbol2str(fund), symbol2str(oper));
405         case ERRONEOUS:
406                 erroneous2int(expp);
407                 break;
408         }
409 }
410
411 opnd2test(expp, oper)
412         register struct expr **expp;
413 {
414         opnd2logical(expp, oper);
415         if ((*expp)->ex_class == Oper) {
416                 if (is_test_op((*expp)->OP_OPER)) {
417                         /* It is already a test */
418                         return;
419                 }
420                 if ((*expp)->OP_OPER == ',') {
421                         opnd2test(&((*expp)->OP_RIGHT), oper);
422                         return;
423                 }
424         }
425         ch7bin(expp, NOTEQUAL, intexpr((arith)0, INT));
426 }
427
428 int
429 is_test_op(oper)
430 {
431         switch (oper)   {
432         case '<':
433         case '>':
434         case LESSEQ:
435         case GREATEREQ:
436         case EQUAL:
437         case NOTEQUAL:
438         case '!':
439         case AND:
440         case OR:        /* && and || also impose a test */
441                 return 1;
442         default:
443                 return 0;
444         }
445         /*NOTREACHED*/
446 }
447
448 any2opnd(expp, oper)
449         register struct expr **expp;
450 {
451         if (!*expp)
452                 return;
453         switch ((*expp)->ex_type->tp_fund)      {       /* RM 7.1 */
454         case CHAR:
455         case SHORT:
456         case ENUM:
457 #ifndef NOFLOAT
458         case FLOAT:
459 #endif /* NOFLOAT */
460                 any2arith(expp, oper);
461                 break;
462         case ARRAY:
463                 array2pointer(*expp);
464                 break;
465         case POINTER:
466                 if ((*expp)->ex_class == String)
467                         string2pointer(*expp);
468                 break;
469 #ifndef NOBITFIELD
470         case FIELD:
471                 field2arith(expp);
472                 break;
473 #endif /* NOBITFIELD */
474         }
475 }
476
477 #ifndef NOBITFIELD
478 field2arith(expp)
479         register struct expr **expp;
480 {
481         /*      The expression to extract the bitfield value from the
482                 memory word is put in the tree.
483         */
484         register struct type *tp = (*expp)->ex_type->tp_up;
485         register struct field *fd = (*expp)->ex_type->tp_field;
486         register struct type *atype = tp->tp_unsigned ? uword_type : word_type;
487
488         (*expp)->ex_type = atype;
489
490         if (atype->tp_unsigned) {       /* don't worry about the sign bit */
491                 ch7bin(expp, RIGHT, intexpr((arith)fd->fd_shift, INT));
492                 ch7bin(expp, '&', intexpr(fd->fd_mask, INT));
493         }
494         else    {       /* take care of the sign bit: sign extend if needed */
495                 arith bits_in_type = atype->tp_size * 8;
496
497                 ch7bin(expp, LEFT,
498                         intexpr(bits_in_type - fd->fd_width - fd->fd_shift,
499                                                 INT)
500                 );
501                 ch7bin(expp, RIGHT, intexpr(bits_in_type - fd->fd_width, INT));
502         }
503         ch7cast(expp, CAST, tp);        /* restore its original type */
504 }
505 #endif /* NOBITFIELD */
506
507 #ifndef NOFLOAT
508 /*      switch_sign_fp() negates the given floating constant expression
509         The lexical analyser has reserved an extra byte of space in front
510         of the string containing the representation of the floating
511         constant.  This byte contains the '-' character and we have to
512         take care of the first byte the fl_value pointer points to.
513 */
514 switch_sign_fp(expr)
515         register struct expr *expr;
516 {
517         if (*(expr->FL_VALUE) == '-')
518                 ++(expr->FL_VALUE);
519         else
520                 --(expr->FL_VALUE);
521 }
522 #endif /* NOFLOAT */