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; | ||||
| 		if (p - str->s_str == len)	{ | ||||
| 			str->s_str = Srealloc(str->s_str, | ||||
| 			str->s_str = Realloc(str->s_str, | ||||
| 				(unsigned int) len + RSTRSIZE); | ||||
| 			p = str->s_str + len; | ||||
| 			len += RSTRSIZE; | ||||
|  |  | |||
|  | @ -1001,6 +1001,7 @@ CodeDAddress(nd) | |||
| 
 | ||||
| 	register struct desig *designator = new_desig(); | ||||
| 
 | ||||
| 	ChkForFOR(nd); | ||||
| 	CodeDesig(nd, designator); | ||||
| 	CodeAddress(designator); | ||||
| 	free_desig(designator); | ||||
|  | @ -1015,6 +1016,7 @@ CodeDStore(nd) | |||
| 
 | ||||
| 	register struct desig *designator = new_desig(); | ||||
| 
 | ||||
| 	ChkForFOR(nd); | ||||
| 	CodeDesig(nd, designator); | ||||
| 	CodeStore(designator, nd->nd_type); | ||||
| 	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_FOREIGN	0x100	/* set for foreign language modules */ | ||||
| #define D_ADDRGIVEN	0x200	/* set if address given for variable */ | ||||
| #define D_FORLOOP	0x400	/* set if busy in for-loop */ | ||||
| 	struct type *df_type; | ||||
| 	union { | ||||
| 		struct module df_module; | ||||
|  |  | |||
|  | @ -30,6 +30,7 @@ | |||
| #include	"scope.h" | ||||
| #include	"desig.h" | ||||
| #include	"node.h" | ||||
| #include	"warning.h" | ||||
| 
 | ||||
| extern int	proclevel; | ||||
| 
 | ||||
|  | @ -165,6 +166,21 @@ CodeValue(ds, tp) | |||
| 	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) | ||||
| 	register struct desig *ds; | ||||
| 	register struct type *tp; | ||||
|  | @ -175,6 +191,7 @@ CodeStore(ds, tp) | |||
| 	struct desig save; | ||||
| 
 | ||||
| 	save = *ds; | ||||
| 
 | ||||
| 	switch(ds->dsg_kind) { | ||||
| 	case DSG_FIXED: | ||||
| 		if (DoStore(ds, tp->tp_size)) break; | ||||
|  | @ -233,6 +250,7 @@ CodeMove(rhs, left, rtp) | |||
| 		generated. | ||||
| 	*/ | ||||
| 
 | ||||
| 	ChkForFOR(left); | ||||
| 	switch(rhs->dsg_kind) { | ||||
| 	case DSG_LOADED: | ||||
| 		CodeDesig(left, lhs); | ||||
|  |  | |||
|  | @ -482,42 +482,66 @@ WalkStat(nd, exit_label) | |||
| 			label l1 = ++text_label; | ||||
| 			label l2 = ++text_label; | ||||
| 			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; | ||||
| 			if (good_forvar) { | ||||
| 				uns = BaseType(nd->nd_type)->tp_fund != T_INTEGER; | ||||
| 				if (fnd->nd_class != Value) { | ||||
| 					/* 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); | ||||
| 				uns = BaseType(nd->nd_type)->tp_fund != | ||||
| 						T_INTEGER; | ||||
| 				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); | ||||
| 				else C_cmi(int_size); | ||||
| 				if (left->nd_INT > 0) { | ||||
| 				if (left->nd_INT >= 0) { | ||||
| 					C_zgt(l2); | ||||
| 					CodeDStore(nd); | ||||
| 					C_lol(tmp); | ||||
| 					CodePExpr(nd); | ||||
| 				} | ||||
| 				else	C_zlt(l2); | ||||
| 				CodeDStore(nd); | ||||
| 				else { | ||||
| 					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); | ||||
| 			if (good_forvar) {	 | ||||
| 				CodePExpr(nd); | ||||
| 			nd->nd_def->df_flags &= ~D_FORLOOP; | ||||
| 			if (stepsize && good_forvar) {	 | ||||
| 				C_loc((arith) 1); | ||||
| 				C_sbu(int_size); | ||||
| 				C_dup(int_size); | ||||
| 				C_zeq(l2); | ||||
| 				C_loc(left->nd_INT); | ||||
| 				if (uns) C_adu(int_size); | ||||
| 				else C_adi(int_size); | ||||
| 				C_bra(l1); | ||||
| 				C_df_ilb(l2); | ||||
| 				C_asp(int_size); | ||||
| 				CodePExpr(nd); | ||||
| 				C_adu(int_size); | ||||
| 				CodeDStore(nd); | ||||
| 			} | ||||
| 			if (tmp) FreeInt(tmp); | ||||
| 			C_bra(l1); | ||||
| 			C_df_ilb(l2); | ||||
| 			C_asp(int_size); | ||||
| 			FreeInt(tmp); | ||||
| #ifdef DEBUG | ||||
| 			nd->nd_left = left; | ||||
| 			nd->nd_right = right; | ||||
|  | @ -642,9 +666,10 @@ WalkDesignator(nd, ds) | |||
| 	return 1; | ||||
| } | ||||
| 
 | ||||
| DoForInit(nd, left) | ||||
| 	register struct node *nd, *left; | ||||
| DoForInit(nd) | ||||
| 	register struct node *nd; | ||||
| { | ||||
| 	register struct node *left = nd->nd_left; | ||||
| 	register struct def *df; | ||||
| 	struct type *tpl, *tpr; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue