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".
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 */
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.
17 #include "nobitfield.h"
26 #include "noRoption.h"
28 extern char *symbol2str();
29 extern char options[];
31 arithbalance(e1p, oper, e2p) /* RM 6.6 */
32 register struct expr **e1p, **e2p;
35 /* The expressions *e1p and *e2p are balanced to be operands
36 of the arithmetic operator oper.
38 register int t1, t2, u1, u2;
40 t1 = any2arith(e1p, oper);
41 t2 = any2arith(e2p, oper);
43 /* Now t1 and t2 are either INT or LONG or DOUBLE */
47 int2float(e2p, double_type);
52 int2float(e1p, double_type);
57 /* Now they are INT or LONG */
58 u1 = (*e1p)->ex_type->tp_unsigned;
59 u2 = (*e2p)->ex_type->tp_unsigned;
61 /* if either is long, the other will be */
62 if (t1 == LONG && t2 != LONG)
63 t2 = int2int(e2p, u2 ? ulong_type : long_type);
65 if (t2 == LONG && t1 != LONG)
66 t1 = int2int(e1p, u1 ? ulong_type : long_type);
68 /* if either is unsigned, the other will be */
70 t2 = int2int(e2p, (t1 == LONG) ? ulong_type : uint_type);
73 t1 = int2int(e1p, (t2 == LONG) ? ulong_type : uint_type);
76 relbalance(e1p, oper, e2p)
77 register struct expr **e1p, **e2p;
79 /* The expressions *e1p and *e2p are balanced to be operands
80 of the relational operator oper.
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);
89 if ((*e2p)->ex_type->tp_fund == POINTER)
90 ch76pointer(e1p, oper, (*e2p)->ex_type);
92 if ( (*e1p)->ex_type == (*e2p)->ex_type &&
93 (*e1p)->ex_type->tp_fund == ENUM
97 arithbalance(e1p, oper, e2p);
100 ch76pointer(expp, oper, tp)
102 register struct type *tp;
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.
108 register struct expr *exp = *expp;
110 if (exp->ex_type->tp_fund == POINTER) {
111 if (exp->ex_type != tp)
112 ch7cast(expp, oper, tp);
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",
121 symbol2str(exp->ex_type->tp_fund)
124 ch7cast(expp, CAST, tp);
127 expr_error(exp, "%s on %s and pointer",
129 symbol2str(exp->ex_type->tp_fund)
131 ch7cast(expp, oper, tp);
136 any2arith(expp, oper)
137 register struct expr **expp;
140 /* Turns any expression into int_type, long_type or
145 switch (fund = (*expp)->ex_type->tp_fund) {
149 (*expp)->ex_type->tp_unsigned ? uint_type : int_type);
155 /* test the admissibility of the operator */
156 if ( is_test_op(oper) || oper == '=' || oper == PARCOMMA ||
157 oper == ',' || oper == ':'
159 /* allowed by K & R */
167 expr_warning(*expp, "%s on enum", symbol2str(oper));
168 #endif /* NOROPTION */
170 int2int(expp, int_type);
175 float2float(expp, double_type);
184 #endif /* NOBITFIELD */
186 expr_error(*expp, "operator %s on non-numerical operand (%s)",
187 symbol2str(oper), symbol2str(fund));
193 return (*expp)->ex_type->tp_fund;
199 /* the (erroneous) expression *expp is replaced by an
202 register struct expr *exp = *expp;
203 int flags = exp->ex_flags;
205 free_expression(exp);
206 exp = intexpr((arith)0, INT);
207 exp->ex_flags = (flags | EX_ERROR);
212 arith2arith(tp, oper, expr)
215 register struct expr *expr;
217 /* arith2arith constructs a new expression containing a
218 run-time conversion between some arithmetic types.
220 register struct expr *new = new_expr();
222 new->ex_file = expr->ex_file;
223 new->ex_line = expr->ex_line;
225 new->ex_class = Type;
226 return new_oper(tp, new, oper, expr);
232 register struct type *tp;
234 /* The expression *expp, which is of some integral type, is
235 converted to the integral type tp.
237 register struct expr *exp = *expp;
239 if (is_cp_cst(exp)) {
240 register struct type *tp1 = exp->ex_type;
243 if (! tp1->tp_unsigned && tp->tp_unsigned) {
244 /* Avoid "unreal" overflow warnings, such as
249 extern long full_mask[];
250 long remainder = exp->VL_VALUE &
251 ~full_mask[(int)(tp->tp_size)];
253 if (remainder == 0 ||
254 remainder == ~full_mask[(int)(tp->tp_size)]) {
255 exp->VL_VALUE &= ~remainder;
261 exp = arith2arith(tp, INT2INT, exp);
264 return exp->ex_type->tp_fund;
269 register struct expr **expp;
272 /* The expression *expp, which is of some integral type, is
273 converted to the floating type tp.
275 register struct expr *exp = *expp;
279 if (is_cp_cst(exp)) {
282 sprint(buf+1, "%ld", (long)(exp->VL_VALUE));
286 exp->ex_class = Float;
287 exp->FL_VALUE = Salloc(buf, (unsigned)strlen(buf)+2) + 1;
290 else *expp = arith2arith(tp, INT2FLOAT, *expp);
297 /* The expression *expp, which is of some floating type, is
298 converted to the integral type tp.
302 *expp = arith2arith(tp, FLOAT2INT, *expp);
305 float2float(expp, tp)
306 register struct expr **expp;
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.
316 if (is_fp_cst(*expp))
317 (*expp)->ex_type = tp;
319 *expp = arith2arith(tp, FLOAT2FLOAT, *expp);
324 register struct expr *exp;
326 /* The expression, which must be an array, is converted
329 exp->ex_type = construct_type(POINTER, exp->ex_type->tp_up, (arith)0);
332 function2pointer(exp)
333 register struct expr *exp;
335 /* The expression, which must be a function, is converted
336 to a pointer to the function.
338 exp->ex_type = construct_type(POINTER, exp->ex_type, (arith)0);
342 register struct expr *ex;
344 /* The expression, which must be a string constant, is converted
345 to a pointer to the string-containing area.
347 label lbl = data_label();
349 code_string(ex->SG_VALUE, ex->SG_LEN, lbl);
350 ex->ex_class = Value;
351 ex->VL_CLASS = Label;
353 ex->VL_VALUE = (arith)0;
356 opnd2integral(expp, oper)
357 register struct expr **expp;
360 register int fund = (*expp)->ex_type->tp_fund;
362 if (fund != INT && fund != LONG) {
363 expr_error(*expp, "%s operand to %s",
364 symbol2str(fund), symbol2str(oper));
370 opnd2logical(expp, oper)
371 register struct expr **expp;
374 int fund = (*expp)->ex_type->tp_fund;
376 if (fund == FUNCTION || fund == ARRAY) {
377 expr_warning(*expp, "%s operand to %s",
380 if (fund == FUNCTION) {
381 function2pointer(*expp);
383 else array2pointer(*expp);
389 #endif /* NOBITFIELD */
390 switch (fund = (*expp)->ex_type->tp_fund) {
403 expr_error(*expp, "%s operand to %s",
404 symbol2str(fund), symbol2str(oper));
411 opnd2test(expp, oper)
412 register struct expr **expp;
414 opnd2logical(expp, oper);
415 if ((*expp)->ex_class == Oper) {
416 if (is_test_op((*expp)->OP_OPER)) {
417 /* It is already a test */
420 if ((*expp)->OP_OPER == ',') {
421 opnd2test(&((*expp)->OP_RIGHT), oper);
425 ch7bin(expp, NOTEQUAL, intexpr((arith)0, INT));
440 case OR: /* && and || also impose a test */
449 register struct expr **expp;
453 switch ((*expp)->ex_type->tp_fund) { /* RM 7.1 */
460 any2arith(expp, oper);
463 array2pointer(*expp);
466 if ((*expp)->ex_class == String)
467 string2pointer(*expp);
473 #endif /* NOBITFIELD */
479 register struct expr **expp;
481 /* The expression to extract the bitfield value from the
482 memory word is put in the tree.
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;
488 (*expp)->ex_type = atype;
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));
494 else { /* take care of the sign bit: sign extend if needed */
495 arith bits_in_type = atype->tp_size * 8;
498 intexpr(bits_in_type - fd->fd_width - fd->fd_shift,
501 ch7bin(expp, RIGHT, intexpr(bits_in_type - fd->fd_width, INT));
503 ch7cast(expp, CAST, tp); /* restore its original type */
505 #endif /* NOBITFIELD */
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.
515 register struct expr *expr;
517 if (*(expr->FL_VALUE) == '-')