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 1.27 1994/06/27 07:59:37 ceriel Exp $ */
6 /* EXPRESSION-CODE GENERATOR */
15 #include "nobitfield.h"
17 #include <flt_arith.h>
35 #define CRASH() crash("EVAL: CRASH at line %u", __LINE__)
39 arith NewLocal(); /* util.c */
40 #define LocalPtrVar() NewLocal(pointer_size, pointer_align, reg_pointer, REGISTER)
41 extern int err_occurred; /* error.c */
43 /* EVAL() is the main expression-tree evaluator, which turns
44 any legal expression tree into EM code. Parameters:
47 pointer to root of the expression tree to be evaluated
50 indicates whether the resulting expression is to be
51 dereferenced (if val == RVAL and expr->ex_lvalue == 1)
52 or not (val == LVAL). The latter case indicates that
53 the resulting expression is an lvalue expression which
54 should not be dereferenced by EVAL
57 indicates whether the expression tree must be turned
58 into EM code or not. E.g. the expression statement "12;"
59 delivers the expression "12" to EVAL while this should
60 not result in any EM code
62 label false_label, label true_label
63 if the expression is a logical or relational expression
64 and if the loop of the program depends on the resulting
65 value then EVAL generates jumps to the specified program
66 labels, in case they are specified (i.e. are non-zero)
69 EVAL(expr, val, code, true_label, false_label)
70 register struct expr *expr;
72 label true_label, false_label;
74 int vol = (code != TRUE && recurqual(expr->ex_type, TQ_VOLATILE));
75 register int gencode = code == TRUE;
77 if (err_occurred) return;
78 switch (expr->ex_class) {
79 case Value: /* just a simple value */
82 /* can only result from ','-expressions with
83 constant right-hand sides ???
85 ASSERT(is_cp_cst(expr));
86 C_bra(expr->VL_VALUE == 0 ? false_label : true_label);
88 else load_val(expr, val);
92 C_asp(ATW(expr->ex_type->tp_size));
95 case String: /* a string constant */
98 C_lae_dlb(expr->VL_LBL, expr->VL_VALUE);
101 case Float: /* a floating constant */
103 label datlab = data_label();
104 char buf[FLT_STRLEN];
107 flt_flt2str(&(expr->FL_ARITH), buf, FLT_STRLEN);
109 C_rom_fcon(buf, expr->ex_type->tp_size);
110 C_lae_dlb(datlab, (arith)0);
111 C_loi(expr->ex_type->tp_size);
114 case Oper: /* compound expression */
116 int oper = expr->OP_OPER;
117 register struct expr *left = expr->OP_LEFT;
118 register struct expr *right = expr->OP_RIGHT;
119 register struct type *tp = expr->OP_TYPE;
123 /* We have the following possibilities :
124 int + int, pointer + int, pointer + long,
125 long + long, double + double
127 operands(expr, gencode);
129 switch (tp->tp_fund) {
138 ptr_add(right->ex_type->tp_size);
151 if (left == 0) { /* unary */
152 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
154 switch (tp->tp_fund) {
171 /* else binary; we have the following flavours:
172 int - int, pointer - int, pointer - long,
173 pointer - pointer, long - long, double - double
175 operands(expr, gencode);
178 switch (tp->tp_fund) {
187 if (right->ex_type->tp_fund == POINTER)
190 C_ngi(right->ex_type->tp_size);
191 ptr_add(right->ex_type->tp_size);
204 if (left == 0) { /* unary */
205 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
206 if (gencode && right->ex_class == String) {
211 operands(expr, gencode);
213 switch (tp->tp_fund) {
233 operands(expr, gencode);
235 switch (tp->tp_fund) {
247 /*C_dvf(double_size);*/
255 operands(expr, gencode);
256 ASSERT(tp->tp_fund==INT || tp->tp_fund==LONG);
264 operands(expr, gencode);
272 operands(expr, gencode);
285 operands(expr, gencode);
287 /* The operands have the same type */
288 arith size = left->ex_type->tp_size;
290 switch (tp->tp_fund) {
293 if (left->ex_type->tp_unsigned)
312 if (true_label != 0) {
313 compare(oper, true_label);
324 /* both operands should have type int */
325 operands(expr, gencode);
327 arith size = tp->tp_size;
329 if ((int)size < (int)word_size)
346 if (left->ex_type->tp_fund == FIELD) {
347 eval_field(expr, gencode);
350 #endif /* NOBITFIELD */
351 if (is_struct_or_union(tp->tp_fund) && ! gencode) {
352 EVAL(right, LVAL, TRUE, NO_LABEL, NO_LABEL);
353 EVAL(left, LVAL, TRUE, NO_LABEL, NO_LABEL);
354 copy_block(tp->tp_size, tp->tp_align);
357 EVAL(right, RVAL, TRUE, NO_LABEL, NO_LABEL);
358 if (gencode && val == RVAL)
359 C_dup(ATW(tp->tp_size));
360 if (left->ex_class != Value) {
361 EVAL(left, LVAL, TRUE, NO_LABEL, NO_LABEL);
362 if (gencode && val == LVAL) {
363 arith tmp = LocalPtrVar();
365 StoreLocal(tmp, pointer_size);
366 store_block(tp->tp_size, tp->tp_align);
367 LoadLocal(tmp, pointer_size);
370 else store_block(tp->tp_size, tp->tp_align);
373 store_val(&(left->EX_VALUE), left->ex_type);
374 if (gencode && val == LVAL) {
375 EVAL(left, LVAL, TRUE, NO_LABEL, NO_LABEL);
395 int compl; /* Complexity of left operand */
399 if (left->ex_type->tp_fund == FIELD) {
400 eval_field(expr, gencode);
403 #endif /* NOBITFIELD */
404 if (left->ex_class == Value) {
405 compl = 0; /* Value */
407 else if (left->ex_depth == 1 &&
408 !(left->ex_flags & EX_SIDEEFFECTS)) {
413 /* evaluate right-hand side first when possible,
414 but not for POSTINCR or PLUSPLUS, because then
415 we might miss a chance for increment instructions.
418 tp->tp_fund != POINTER &&
419 (oper == PLUSAB || oper == TIMESAB ||
420 oper == ANDAB || oper == XORAB || oper == ORAB)) {
422 EVAL(right, RVAL, TRUE, NO_LABEL, NO_LABEL);
425 load_val(left, RVAL);
429 EVAL(left, RVAL, TRUE, NO_LABEL, NO_LABEL);
432 EVAL(left, LVAL, TRUE, NO_LABEL, NO_LABEL);
435 StoreLocal(tmp, pointer_size);
436 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);
443 EVAL(right, RVAL, TRUE, NO_LABEL, NO_LABEL);
445 dupval = gencode && oper != POSTINCR &&
448 conversion(tp, left->ex_type);
450 store_val(&(left->EX_VALUE),
452 if (dupval) load_val(left, RVAL);
454 else if (compl == 1) {
455 EVAL(left, LVAL, TRUE, NO_LABEL, NO_LABEL);
456 C_sti(left->ex_type->tp_size);
458 EVAL(left, LVAL, TRUE, NO_LABEL, NO_LABEL);
459 C_loi(left->ex_type->tp_size);
463 LoadLocal(tmp, pointer_size);
464 C_sti(left->ex_type->tp_size);
466 LoadLocal(tmp, pointer_size);
467 C_loi(left->ex_type->tp_size);
475 register struct expr *ex;
476 arith ParSize = (arith)0;
477 label setjmp_label = 0;
481 if (left->VL_IDF->id_special == SP_SETJMP) {
482 label addr_label = data_label();
484 setjmp_label = text_label();
485 C_df_dlb(addr_label);
486 C_rom_ilb(setjmp_label);
487 C_lae_dlb(addr_label, (arith) 0);
489 ParSize += pointer_size;
492 if ((ex = right) != NILEXPR) {
493 /* function call with parameters*/
494 while ( ex->ex_class == Oper &&
495 ex->OP_OPER == PARCOMMA
497 EVAL(ex->OP_RIGHT, RVAL, TRUE,
499 ParSize += ATW(ex->OP_RIGHT->ex_type->tp_size);
502 EVAL(ex, RVAL, TRUE, NO_LABEL, NO_LABEL);
503 ParSize += ATW(ex->ex_type->tp_size);
505 if (is_struct_or_union(tp->tp_fund)) {
506 retspace = NewLocal(tp->tp_size, tp->tp_align,
509 ParSize += pointer_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)) {
536 load_block(tp->tp_size, (int) word_size);
541 C_lfr(ATW(tp->tp_size));
543 if (tp->tp_fund == FLOAT || tp->tp_fund == DOUBLE
544 || tp->tp_fund == LNGDBL)
546 /* ??? set filename and line number ??? */
551 if (tp->tp_fund == FLOAT || tp->tp_fund == DOUBLE
552 || tp->tp_fund == LNGDBL)
554 EVAL(left, oper == '.' ? LVAL : RVAL, gencode,
556 ASSERT(is_cp_cst(right));
558 C_adp(right->VL_VALUE);
562 EVAL(left, RVAL, FALSE, NO_LABEL, NO_LABEL);
563 EVAL(right, val, gencode, true_label, false_label);
566 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
570 case '?': /* must be followed by ':' */
572 label l_true = text_label();
573 label l_false = text_label();
574 label l_end = text_label();
576 EVAL(left, RVAL, TRUE, l_true, l_false);
578 EVAL(right->OP_LEFT, val, gencode, NO_LABEL, NO_LABEL);
581 EVAL(right->OP_RIGHT, val, gencode, NO_LABEL, NO_LABEL);
587 label l_false, l_true, l_maybe;
589 l_maybe = text_label();
591 l_false = false_label;
595 l_false = text_label();
596 l_true = gencode ? text_label(): l_false;
599 EVAL(left, RVAL, TRUE, oper == AND ? l_maybe : l_true,
600 oper == AND ? l_false : l_maybe);
602 EVAL(right, RVAL, gencode, l_true, l_false);
603 if (gencode && !true_label) {
604 label l_end = text_label();
614 if (! true_label) C_df_ilb(l_false);
619 if (true_label == 0) {
620 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
626 EVAL(right, RVAL, gencode, false_label,
633 EVAL(right, RVAL, gencode, NO_LABEL, NO_LABEL);
635 conversion(right->ex_type, left->ex_type);
638 crash("(EVAL) bad operator %s\n", symbol2str(oper));
640 /* If the rvalue of the expression is required but
641 only its lvalue is evaluated, its rvalue is
642 loaded by the following statements:
644 if (gencode && val == RVAL && expr->ex_lvalue == 1) {
645 if (expr->ex_type->tp_fund == FLOAT
646 || expr->ex_type->tp_fund == DOUBLE
647 || expr->ex_type->tp_fund == LNGDBL)
649 load_block(expr->ex_type->tp_size,
650 expr->ex_type->tp_align);
655 crash("(EVAL) bad expression class");
657 if (val == RVAL && ((expr->ex_flags & EX_VOLATILE) || vol)) C_nop();
660 /* compare() serves as an auxiliary function of EVAL */
689 /* truthvalue() serves as an auxiliary function of EVAL */
718 /* assop() generates the opcode of an assignment operators op= */
720 register struct type *type;
724 register uns = type->tp_unsigned;
726 if ((int)(size = type->tp_size) < (int)word_size)
728 switch (type->tp_fund) {
797 case PLUSPLUS: /* ??? etc... */
815 if (oper == MINAB || oper == MINMIN || oper == POSTDECR)
820 crash("(assop) bad type %s\n", symbol2str(type->tp_fund));
827 if (size != pointer_size) {
835 /* store_val() generates code for a store operation.
836 There are four ways of storing data:
837 - into a global variable
838 - into an automatic local variable
839 - into a local static variable
840 - absolute addressing
843 register struct value *vl;
844 register struct type *tp;
846 register int inword = 0;
847 register int indword = 0;
848 arith val = vl->vl_value;
850 if (vl->vl_class == Const) { /* absolute addressing */
851 load_cst(val, pointer_size);
852 store_block(tp->tp_size, tp->tp_align);
855 if (tp->tp_align % word_align == 0) {
856 if (tp->tp_size == word_size) inword = 1;
857 else if (tp->tp_size == dword_size) indword = 1;
859 if (vl->vl_class == Name) {
860 register struct idf *id = vl->vl_data.vl_idf;
861 register struct def *df = id->id_def;
863 /* if (df->df_level == L_GLOBAL) { /* } ??? re-examine */
864 if (df->df_sc == GLOBAL
865 || df->df_sc == EXTERN
866 || df->df_sc == STATIC) {
868 C_ste_dnam(id->id_text, val);
871 C_sde_dnam(id->id_text, val);
873 C_lae_dnam(id->id_text, val);
874 store_block(tp->tp_size, tp->tp_align);
878 ASSERT(df->df_sc != STATIC);
879 if (inword || indword)
880 StoreLocal(df->df_address + val, tp->tp_size);
882 AddrLocal(df->df_address + val);
883 store_block(tp->tp_size, tp->tp_align);
888 label dlb = vl->vl_data.vl_lbl;
890 ASSERT(vl->vl_class == Label);
898 store_block(tp->tp_size, tp->tp_align);
904 /* load_val() generates code for stacking a certain value (from ex),
905 which can be obtained in one of the following ways:
906 - value from absolute addressed memory
913 load_val(expr, rlval)
914 register struct expr *expr; /* expression containing the value */
915 int rlval; /* generate either LVAL or RVAL */
917 register struct type *tp = expr->ex_type;
918 int rvalue = (rlval == RVAL && expr->ex_lvalue != 0);
919 register int inword = 0, indword = 0;
920 register arith val = expr->VL_VALUE;
922 if (expr->ex_type->tp_fund == FLOAT
923 || expr->ex_type->tp_fund == DOUBLE
924 || expr->ex_type->tp_fund == LNGDBL)
926 if (expr->VL_CLASS == Const) {
927 if (rvalue) { /* absolute addressing */
928 load_cst(val, pointer_size);
929 load_block(tp->tp_size, tp->tp_align);
931 else /* integer, unsigned, long, enum etc */
932 load_cst(val, tp->tp_size);
936 if (tp->tp_align % word_align == 0) {
937 if (tp->tp_size == word_size) inword = 1;
938 else if (tp->tp_size == dword_size) indword = 1;
941 if (expr->VL_CLASS == Label) {
944 C_loe_dlb(expr->VL_LBL, val);
947 C_lde_dlb(expr->VL_LBL, val);
949 C_lae_dlb(expr->VL_LBL, val);
950 load_block(tp->tp_size, tp->tp_align);
955 C_lae_dlb(expr->VL_LBL, (arith)0);
960 register struct idf *id = expr->VL_IDF;
961 register struct def *df = id->id_def;
962 int fund = df->df_type->tp_fund;
964 ASSERT(ISNAME(expr));
965 if (fund == FUNCTION) {
966 /* the previous statement tried to catch a function
967 identifier, which may be cast to a pointer to a
969 ASSERT(!(rvalue)); ???
974 /* if (df->df_level == L_GLOBAL) { /* } ??? re-examine */
975 if ( df->df_sc == GLOBAL
976 || df->df_sc == STATIC
977 || df->df_sc == EXTERN) {
980 C_loe_dnam(id->id_text, val);
983 C_lde_dnam(id->id_text, val);
985 C_lae_dnam(id->id_text, val);
986 load_block(tp->tp_size, tp->tp_align);
990 C_lae_dnam(id->id_text, (arith)0);
995 /* ASSERT(df->df_sc != STATIC); */
997 if (inword || indword)
998 LoadLocal(df->df_address + val, tp->tp_size);
1000 AddrLocal(df->df_address + val);
1001 load_block(tp->tp_size, tp->tp_align);
1005 AddrLocal(df->df_address);
1015 if ((int)siz <= (int)word_size)
1018 if ((int)siz == (int)dword_size)
1023 C_df_dlb(datlab = data_label());
1024 C_rom_icon(long2str((long)val, 10), siz);
1025 C_lae_dlb(datlab, (arith)0);
1030 operands(expr, gencode)
1031 register struct expr *expr;
1033 EVAL(expr->OP_LEFT, RVAL, gencode, NO_LABEL, NO_LABEL);
1034 EVAL(expr->OP_RIGHT, RVAL, gencode, NO_LABEL, NO_LABEL);