Generated code for FOR-loops was wrong
This commit is contained in:
		
							parent
							
								
									e5af61151e
								
							
						
					
					
						commit
						abf9c71fa9
					
				
					 5 changed files with 73 additions and 27 deletions
				
			
		| 
						 | 
					@ -123,7 +123,7 @@ GetString(upto)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		*p++ = ch;
 | 
							*p++ = ch;
 | 
				
			||||||
		if (p - str->s_str == len)	{
 | 
							if (p - str->s_str == len)	{
 | 
				
			||||||
			str->s_str = Srealloc(str->s_str,
 | 
								str->s_str = Realloc(str->s_str,
 | 
				
			||||||
				(unsigned int) len + RSTRSIZE);
 | 
									(unsigned int) len + RSTRSIZE);
 | 
				
			||||||
			p = str->s_str + len;
 | 
								p = str->s_str + len;
 | 
				
			||||||
			len += RSTRSIZE;
 | 
								len += RSTRSIZE;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1001,6 +1001,7 @@ CodeDAddress(nd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	register struct desig *designator = new_desig();
 | 
						register struct desig *designator = new_desig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ChkForFOR(nd);
 | 
				
			||||||
	CodeDesig(nd, designator);
 | 
						CodeDesig(nd, designator);
 | 
				
			||||||
	CodeAddress(designator);
 | 
						CodeAddress(designator);
 | 
				
			||||||
	free_desig(designator);
 | 
						free_desig(designator);
 | 
				
			||||||
| 
						 | 
					@ -1015,6 +1016,7 @@ CodeDStore(nd)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	register struct desig *designator = new_desig();
 | 
						register struct desig *designator = new_desig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ChkForFOR(nd);
 | 
				
			||||||
	CodeDesig(nd, designator);
 | 
						CodeDesig(nd, designator);
 | 
				
			||||||
	CodeStore(designator, nd->nd_type);
 | 
						CodeStore(designator, nd->nd_type);
 | 
				
			||||||
	free_desig(designator);
 | 
						free_desig(designator);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -113,6 +113,7 @@ struct def	{		/* list of definitions for a name */
 | 
				
			||||||
#define D_BUSY		0x80	/* set if busy reading this definition module */
 | 
					#define D_BUSY		0x80	/* set if busy reading this definition module */
 | 
				
			||||||
#define D_FOREIGN	0x100	/* set for foreign language modules */
 | 
					#define D_FOREIGN	0x100	/* set for foreign language modules */
 | 
				
			||||||
#define D_ADDRGIVEN	0x200	/* set if address given for variable */
 | 
					#define D_ADDRGIVEN	0x200	/* set if address given for variable */
 | 
				
			||||||
 | 
					#define D_FORLOOP	0x400	/* set if busy in for-loop */
 | 
				
			||||||
	struct type *df_type;
 | 
						struct type *df_type;
 | 
				
			||||||
	union {
 | 
						union {
 | 
				
			||||||
		struct module df_module;
 | 
							struct module df_module;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,6 +30,7 @@
 | 
				
			||||||
#include	"scope.h"
 | 
					#include	"scope.h"
 | 
				
			||||||
#include	"desig.h"
 | 
					#include	"desig.h"
 | 
				
			||||||
#include	"node.h"
 | 
					#include	"node.h"
 | 
				
			||||||
 | 
					#include	"warning.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern int	proclevel;
 | 
					extern int	proclevel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -165,6 +166,21 @@ CodeValue(ds, tp)
 | 
				
			||||||
	ds->dsg_kind = DSG_LOADED;
 | 
						ds->dsg_kind = DSG_LOADED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ChkForFOR(nd)
 | 
				
			||||||
 | 
						struct node *nd;
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if (nd->nd_class == Def) {
 | 
				
			||||||
 | 
							register struct def *df = nd->nd_def;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (df->df_flags & D_FORLOOP) {
 | 
				
			||||||
 | 
								node_warning(nd,
 | 
				
			||||||
 | 
									     W_ORDINARY,
 | 
				
			||||||
 | 
									     "assignment to FOR-loop control variable");
 | 
				
			||||||
 | 
								df->df_flags &= ~D_FORLOOP;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
CodeStore(ds, tp)
 | 
					CodeStore(ds, tp)
 | 
				
			||||||
	register struct desig *ds;
 | 
						register struct desig *ds;
 | 
				
			||||||
	register struct type *tp;
 | 
						register struct type *tp;
 | 
				
			||||||
| 
						 | 
					@ -175,6 +191,7 @@ CodeStore(ds, tp)
 | 
				
			||||||
	struct desig save;
 | 
						struct desig save;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	save = *ds;
 | 
						save = *ds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch(ds->dsg_kind) {
 | 
						switch(ds->dsg_kind) {
 | 
				
			||||||
	case DSG_FIXED:
 | 
						case DSG_FIXED:
 | 
				
			||||||
		if (DoStore(ds, tp->tp_size)) break;
 | 
							if (DoStore(ds, tp->tp_size)) break;
 | 
				
			||||||
| 
						 | 
					@ -233,6 +250,7 @@ CodeMove(rhs, left, rtp)
 | 
				
			||||||
		generated.
 | 
							generated.
 | 
				
			||||||
	*/
 | 
						*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ChkForFOR(left);
 | 
				
			||||||
	switch(rhs->dsg_kind) {
 | 
						switch(rhs->dsg_kind) {
 | 
				
			||||||
	case DSG_LOADED:
 | 
						case DSG_LOADED:
 | 
				
			||||||
		CodeDesig(left, lhs);
 | 
							CodeDesig(left, lhs);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -482,42 +482,66 @@ WalkStat(nd, exit_label)
 | 
				
			||||||
			label l1 = ++text_label;
 | 
								label l1 = ++text_label;
 | 
				
			||||||
			label l2 = ++text_label;
 | 
								label l2 = ++text_label;
 | 
				
			||||||
			int uns = 0;
 | 
								int uns = 0;
 | 
				
			||||||
 | 
								arith stepsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			good_forvar = DoForInit(nd, left);
 | 
								good_forvar = DoForInit(nd);
 | 
				
			||||||
 | 
								if ((stepsize = left->nd_INT) == 0) {
 | 
				
			||||||
 | 
								    node_warning(left,
 | 
				
			||||||
 | 
										 W_ORDINARY,
 | 
				
			||||||
 | 
										 "zero stepsize in FOR loop");
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (stepsize < 0) {
 | 
				
			||||||
 | 
									stepsize = -stepsize;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			fnd = left->nd_right;
 | 
								fnd = left->nd_right;
 | 
				
			||||||
			if (good_forvar) {
 | 
								if (good_forvar) {
 | 
				
			||||||
				uns = BaseType(nd->nd_type)->tp_fund != T_INTEGER;
 | 
									uns = BaseType(nd->nd_type)->tp_fund !=
 | 
				
			||||||
				if (fnd->nd_class != Value) {
 | 
											T_INTEGER;
 | 
				
			||||||
					/* Upperbound not constant.
 | 
					 | 
				
			||||||
					   The expression may only be evaluated
 | 
					 | 
				
			||||||
					   once, so generate a temporary for it
 | 
					 | 
				
			||||||
					*/
 | 
					 | 
				
			||||||
					CodePExpr(fnd);
 | 
					 | 
				
			||||||
					tmp = NewInt();
 | 
					 | 
				
			||||||
					C_stl(tmp);
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				C_df_ilb(l1);
 | 
					 | 
				
			||||||
				C_dup(int_size);
 | 
									C_dup(int_size);
 | 
				
			||||||
				if (tmp) C_lol(tmp); else C_loc(fnd->nd_INT);
 | 
									CodePExpr(fnd);
 | 
				
			||||||
 | 
									tmp = NewInt();
 | 
				
			||||||
 | 
									C_stl(tmp);
 | 
				
			||||||
 | 
									C_lol(tmp);
 | 
				
			||||||
				if (uns) C_cmu(int_size);
 | 
									if (uns) C_cmu(int_size);
 | 
				
			||||||
				else C_cmi(int_size);
 | 
									else C_cmi(int_size);
 | 
				
			||||||
				if (left->nd_INT > 0) {
 | 
									if (left->nd_INT >= 0) {
 | 
				
			||||||
					C_zgt(l2);
 | 
										C_zgt(l2);
 | 
				
			||||||
 | 
										CodeDStore(nd);
 | 
				
			||||||
 | 
										C_lol(tmp);
 | 
				
			||||||
 | 
										CodePExpr(nd);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				else	C_zlt(l2);
 | 
									else {
 | 
				
			||||||
				CodeDStore(nd);
 | 
										C_zlt(l2);
 | 
				
			||||||
 | 
										CodeDStore(nd);
 | 
				
			||||||
 | 
										CodePExpr(nd);
 | 
				
			||||||
 | 
										C_lol(tmp);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									C_sbu(int_size);
 | 
				
			||||||
 | 
									if (stepsize) {
 | 
				
			||||||
 | 
										C_loc(stepsize);
 | 
				
			||||||
 | 
										C_dvu(int_size);
 | 
				
			||||||
 | 
										C_loc((arith) 1);
 | 
				
			||||||
 | 
										C_adu(int_size);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									nd->nd_def->df_flags |= D_FORLOOP;
 | 
				
			||||||
 | 
									C_df_ilb(l1);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			WalkNode(right, exit_label);
 | 
								WalkNode(right, exit_label);
 | 
				
			||||||
			if (good_forvar) {	
 | 
								nd->nd_def->df_flags &= ~D_FORLOOP;
 | 
				
			||||||
				CodePExpr(nd);
 | 
								if (stepsize && good_forvar) {	
 | 
				
			||||||
 | 
									C_loc((arith) 1);
 | 
				
			||||||
 | 
									C_sbu(int_size);
 | 
				
			||||||
 | 
									C_dup(int_size);
 | 
				
			||||||
 | 
									C_zeq(l2);
 | 
				
			||||||
				C_loc(left->nd_INT);
 | 
									C_loc(left->nd_INT);
 | 
				
			||||||
				if (uns) C_adu(int_size);
 | 
									CodePExpr(nd);
 | 
				
			||||||
				else C_adi(int_size);
 | 
									C_adu(int_size);
 | 
				
			||||||
				C_bra(l1);
 | 
									CodeDStore(nd);
 | 
				
			||||||
				C_df_ilb(l2);
 | 
					 | 
				
			||||||
				C_asp(int_size);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if (tmp) FreeInt(tmp);
 | 
								C_bra(l1);
 | 
				
			||||||
 | 
								C_df_ilb(l2);
 | 
				
			||||||
 | 
								C_asp(int_size);
 | 
				
			||||||
 | 
								FreeInt(tmp);
 | 
				
			||||||
#ifdef DEBUG
 | 
					#ifdef DEBUG
 | 
				
			||||||
			nd->nd_left = left;
 | 
								nd->nd_left = left;
 | 
				
			||||||
			nd->nd_right = right;
 | 
								nd->nd_right = right;
 | 
				
			||||||
| 
						 | 
					@ -642,9 +666,10 @@ WalkDesignator(nd, ds)
 | 
				
			||||||
	return 1;
 | 
						return 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DoForInit(nd, left)
 | 
					DoForInit(nd)
 | 
				
			||||||
	register struct node *nd, *left;
 | 
						register struct node *nd;
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						register struct node *left = nd->nd_left;
 | 
				
			||||||
	register struct def *df;
 | 
						register struct def *df;
 | 
				
			||||||
	struct type *tpl, *tpr;
 | 
						struct type *tpl, *tpr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue