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: eval.c,v 3.39 1994/06/24 12:03:33 ceriel Exp $ */
6 /* EXPRESSION-CODE GENERATOR */
15 #include "nobitfield.h"
34 #define CRASH() crash("EVAL: CRASH at line %u", __LINE__)
38 arith NewLocal(); /* util.c */
39 #define LocalPtrVar() NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER)
41 /* EVAL() is the main expression-tree evaluator, which turns
42 any legal expression tree into EM code. Parameters:
45 pointer to root of the expression tree to be evaluated
48 indicates whether the resulting expression is to be
49 dereferenced (if val == RVAL and expr->ex_lvalue == 1)
50 or not (val == LVAL). The latter case indicates that
51 the resulting expression is an lvalue expression which
52 should not be dereferenced by EVAL
55 indicates whether the expression tree must be turned
56 into EM code or not. E.g. the expression statement "12;"
57 delivers the expression "12" to EVAL while this should
58 not result in any EM code
60 label false_label, label true_label
61 if the expression is a logical or relational expression
62 and if the loop of the program depends on the resulting
63 value then EVAL generates jumps to the specified program
64 labels, in case they are specified (i.e. are non-zero)
67 EVAL(expr, val, code, true_label, false_label)
68 register struct expr *expr;
70 label true_label, false_label;
72 register int gencode = (code == TRUE && expr->ex_type->tp_size > 0);
74 switch (expr->ex_class) {
75 case Value: /* just a simple value */
78 /* can only result from ','-expressions with
79 constant right-hand sides ???
81 ASSERT(is_cp_cst(expr));
82 C_bra(expr->VL_VALUE == 0 ? false_label : true_label);
84 else load_val(expr, val);
87 case String: /* a string constant */
90 C_lae_dlb(expr->VL_LBL, expr->VL_VALUE);
94 case Float: /* a floating constant */
96 label datlab = data_label();
99 C_rom_fcon(expr->FL_VALUE, expr->ex_type->tp_size);
100 C_lae_dlb(datlab, (arith)0);
101 C_loi(expr->ex_type->tp_size);
105 case Oper: /* compound expression */
107 int oper = expr->OP_OPER;
108 register struct expr *left = expr->OP_LEFT;
109 register struct expr *right = expr->OP_RIGHT;
110 register struct type *tp = expr->OP_TYPE;
112 if (tp->tp_fund == ERRONEOUS || (expr->ex_flags & EX_ERROR)) {
113 /* stop immediately */
116 if (tp->tp_fund == VOID)
120 /* We have the following possibilities :
121 int + int, pointer + int, pointer + long,
122 long + long, double + double
124 EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL);
125 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
127 switch (tp->tp_fund) {
136 C_loc(right->ex_type->tp_size);
152 if (left == 0) { /* unary */
153 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
155 switch (tp->tp_fund) {
172 /* else binary; we have the following flavours:
173 int - int, pointer - int, pointer - long,
174 pointer - pointer, long - long, double - double
176 EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL);
177 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
180 switch (tp->tp_fund) {
189 if (right->ex_type->tp_fund == POINTER)
192 C_ngi(right->ex_type->tp_size);
193 C_loc(right->ex_type->tp_size);
209 if (left == 0) { /* unary */
210 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
211 if (gencode && right->ex_class == String) {
216 EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL);
217 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
219 switch (tp->tp_fund) {
239 EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL);
240 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
242 switch (tp->tp_fund) {
261 EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL);
262 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
263 ASSERT(tp->tp_fund==INT || tp->tp_fund==LONG);
271 EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL);
272 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
280 EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL);
281 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
294 EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL);
295 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
297 /* The operands have the same type */
298 arith size = left->ex_type->tp_size;
300 switch (tp->tp_fund) {
303 if (left->ex_type->tp_unsigned)
309 case FLOAT: /* thought they were converted??? */
323 if (true_label != 0) {
324 compare(oper, true_label);
335 /* both operands should have type int */
336 EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL);
337 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
339 arith size = tp->tp_size;
341 if ((int)size < (int)word_size)
357 int newcode = tp->tp_size > 0; /* CJ */
359 if (left->ex_type->tp_fund == FIELD) {
360 eval_field(expr, gencode);
363 #endif /* NOBITFIELD */
364 EVAL(right, RVAL, newcode, NO_LABEL, NO_LABEL);
366 C_dup(ATW(tp->tp_size));
367 if (left->ex_class != Value) {
368 EVAL(left, LVAL, newcode, NO_LABEL, NO_LABEL);
370 store_block(tp->tp_size, tp->tp_align);
373 store_val(&(left->EX_VALUE), left->ex_type);
392 int compl; /* Complexity of left operand */
393 int newcode = left->ex_type->tp_size > 0; /* CJ */
396 if (left->ex_type->tp_fund == FIELD) {
397 eval_field(expr, gencode);
400 #endif /* NOBITFIELD */
401 if (newcode && left->ex_class == Value) {
402 compl = 0; /* Value */
404 else if (left->ex_depth == 1 &&
405 !(left->ex_flags & EX_SIDEEFFECTS)) {
410 /* evaluate right-hand side first when possible,
411 but not for POSTINCR or PLUSPLUS, because then
412 we might miss a chance for increment instructions.
415 tp->tp_fund != POINTER &&
416 (oper == PLUSAB || oper == TIMESAB ||
417 oper == ANDAB || oper == XORAB || oper == ORAB)) {
419 EVAL(right, RVAL, newcode, NO_LABEL, NO_LABEL);
422 load_val(left, RVAL);
426 EVAL(left, RVAL, newcode, NO_LABEL, NO_LABEL);
429 EVAL(left, LVAL, newcode, NO_LABEL, NO_LABEL);
433 StoreLocal(tmp, pointer_size);
434 C_loi(left->ex_type->tp_size);
438 if (gencode && (oper == POSTINCR ||
440 C_dup(ATW(left->ex_type->tp_size));
441 conversion(left->ex_type, tp);
444 EVAL(right, RVAL, newcode, NO_LABEL, NO_LABEL);
447 int dupval = gencode && oper != POSTINCR &&
450 conversion(tp, left->ex_type);
452 store_val(&(left->EX_VALUE),
454 if (dupval) load_val(left, RVAL);
456 else if (compl == 1) {
457 EVAL(left, LVAL,1, NO_LABEL, NO_LABEL);
458 C_sti(left->ex_type->tp_size);
460 EVAL(left, LVAL, 1, NO_LABEL,
462 C_loi(left->ex_type->tp_size);
466 LoadLocal(tmp, pointer_size);
467 C_sti(left->ex_type->tp_size);
469 LoadLocal(tmp, pointer_size);
470 C_loi(left->ex_type->tp_size);
479 register struct expr *ex;
480 arith ParSize = (arith)0;
481 label setjmp_label = 0;
484 if (left->VL_IDF->id_special == SP_SETJMP) {
485 label addr_label = data_label();
487 setjmp_label = text_label();
488 C_df_dlb(addr_label);
489 C_rom_ilb(setjmp_label);
490 C_lae_dlb(addr_label, (arith) 0);
492 ParSize += pointer_size;
495 if ((ex = right) != NILEXPR) {
496 /* function call with parameters*/
497 while ( ex->ex_class == Oper &&
498 ex->OP_OPER == PARCOMMA
500 register struct expr *rght = ex->OP_RIGHT;
502 rght->ex_type->tp_size > 0,
504 ParSize += ATW(rght->ex_type->tp_size);
507 EVAL(ex, RVAL, ex->ex_type->tp_size > 0,
509 ParSize += ATW(ex->ex_type->tp_size);
512 /* e.g., main() { (*((int (*)())0))(); } */
513 C_cal(left->VL_IDF->id_text);
515 C_df_ilb(setjmp_label);
518 { extern char options[];
521 left->VL_IDF->id_text);
523 #endif /* DATAFLOW */
526 EVAL(left, LVAL, TRUE, NO_LABEL, NO_LABEL);
529 /* remove parameters from stack */
530 if (ParSize > (arith)0)
533 if (is_struct_or_union(tp->tp_fund)) {
535 load_block(tp->tp_size, (int) word_size);
538 C_lfr(ATW(tp->tp_size));
543 EVAL(left, LVAL, gencode, NO_LABEL, NO_LABEL);
544 ASSERT(is_cp_cst(right));
546 C_adp(right->VL_VALUE);
549 EVAL(left, RVAL, gencode, NO_LABEL, NO_LABEL);
550 ASSERT(is_cp_cst(right));
552 C_adp(right->VL_VALUE);
555 EVAL(left, RVAL, FALSE, NO_LABEL, NO_LABEL);
556 EVAL(right, RVAL, gencode, true_label, false_label);
559 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
563 case '?': /* must be followed by ':' */
565 label l_true = text_label();
566 label l_false = text_label();
567 label l_end = text_label();
569 EVAL(left, RVAL, TRUE, l_true, l_false);
571 EVAL(right->OP_LEFT, RVAL, gencode, NO_LABEL, NO_LABEL);
574 EVAL(right->OP_RIGHT, RVAL, gencode, NO_LABEL, NO_LABEL);
580 label l_false, l_true, l_maybe;
582 l_maybe = text_label();
584 l_false = false_label;
588 l_false = text_label();
589 l_true = gencode ? text_label(): l_false;
592 EVAL(left, RVAL, TRUE, oper == AND ? l_maybe : l_true,
593 oper == AND ? l_false : l_maybe);
595 EVAL(right, RVAL, gencode, l_true, l_false);
596 if (gencode && !true_label) {
597 label l_end = text_label();
607 if (! true_label) C_df_ilb(l_false);
612 if (true_label == 0) {
613 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
619 EVAL(right, RVAL, gencode, false_label,
628 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
630 conversion(right->ex_type, left->ex_type);
633 crash("(EVAL) bad operator %s\n", symbol2str(oper));
635 /* If the rvalue of the expression is required but
636 only its lvalue is evaluated, its rvalue is
637 loaded by the following statements:
639 if (gencode && val == RVAL && expr->ex_lvalue == 1)
640 load_block(expr->ex_type->tp_size,
641 expr->ex_type->tp_align);
645 crash("(EVAL) bad expression class");
649 /* compare() serves as an auxiliary function of EVAL */
678 /* truthvalue() serves as an auxiliary function of EVAL */
707 /* assop() generates the opcode of an assignment operators op= */
709 register struct type *type;
713 register uns = type->tp_unsigned;
715 if ((int)(size = type->tp_size) < (int)word_size)
717 switch (type->tp_fund) {
805 if (oper == MINAB || oper == MINMIN || oper == POSTDECR)
815 crash("(assop) bad type %s\n", symbol2str(type->tp_fund));
819 /* store_val() generates code for a store operation.
820 There are four ways of storing data:
821 - into a global variable
822 - into an automatic local variable
823 - into a local static variable
824 - absolute addressing
827 register struct value *vl;
830 arith size = tp->tp_size;
831 int tpalign = tp->tp_align;
834 register int indword;
835 arith val = vl->vl_value;
837 if (vl->vl_class == Const) { /* absolute addressing */
838 load_cst(val, pointer_size);
839 store_block(size, tpalign);
842 al_on_word = (tpalign % word_align == 0);
843 if (!(inword = (size == word_size && al_on_word)))
844 indword = (size == dword_size && al_on_word);
845 if (vl->vl_class == Name) {
846 register struct idf *id = vl->vl_data.vl_idf;
847 register struct def *df = id->id_def;
849 if (df->df_level == L_GLOBAL) {
851 C_ste_dnam(id->id_text, val);
854 C_sde_dnam(id->id_text, val);
856 C_lae_dnam(id->id_text, val);
857 store_block(size, tpalign);
861 ASSERT(df->df_sc != STATIC);
862 if (inword || indword)
863 StoreLocal(df->df_address + val, size);
865 AddrLocal(df->df_address + val);
866 store_block(size, tpalign);
871 label dlb = vl->vl_data.vl_lbl;
873 ASSERT(vl->vl_class == Label);
881 store_block(size, tpalign);
887 /* load_val() generates code for stacking a certain value (from ex),
888 which can be obtained in one of the following ways:
889 - value from absolute addressed memory
896 load_val(expr, rlval)
897 register struct expr *expr; /* expression containing the value */
898 int rlval; /* generate either LVAL or RVAL */
900 register struct type *tp = expr->ex_type;
901 int rvalue = (rlval == RVAL && expr->ex_lvalue != 0);
902 arith size = tp->tp_size;
903 int tpalign = tp->tp_align;
905 register int inword, indword;
906 register arith val = expr->VL_VALUE;
908 if (expr->VL_CLASS == Const) {
909 if (rvalue) { /* absolute addressing */
910 load_cst(val, pointer_size);
911 load_block(size, tpalign);
913 else /* integer, unsigned, long, enum etc */
918 al_on_word = (tpalign % word_align == 0);
919 if (!(inword = (size == word_size && al_on_word)))
920 indword = (size == dword_size && al_on_word);
922 if (expr->VL_CLASS == Label) {
925 C_loe_dlb(expr->VL_LBL, val);
928 C_lde_dlb(expr->VL_LBL, val);
930 C_lae_dlb(expr->VL_LBL, val);
931 load_block(size, tpalign);
936 C_lae_dlb(expr->VL_LBL, (arith)0);
941 register struct idf *id = expr->VL_IDF;
942 register struct def *df = id->id_def;
944 ASSERT(ISNAME(expr));
945 if (df->df_type->tp_fund == FUNCTION) {
946 /* the previous statement tried to catch a function
947 identifier, which may be cast to a pointer to a
949 ASSERT(!(rvalue)); ???
954 if (df->df_level == L_GLOBAL) {
957 C_loe_dnam(id->id_text, val);
960 C_lde_dnam(id->id_text, val);
962 C_lae_dnam(id->id_text, val);
963 load_block(size, tpalign);
967 C_lae_dnam(id->id_text, (arith)0);
972 ASSERT(df->df_sc != STATIC);
974 if (inword || indword)
975 LoadLocal(df->df_address + val, size);
977 AddrLocal(df->df_address + val);
978 load_block(size, tpalign);
982 AddrLocal(df->df_address);
992 if (siz <= word_size)
995 if (siz == dword_size)
1000 C_df_dlb(datlab = data_label());
1001 C_rom_icon(long2str((long)val, 10), siz);
1002 C_lae_dlb(datlab, (arith)0);