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.
|
C_dup(int_size);
|
||||||
The expression may only be evaluated
|
|
||||||
once, so generate a temporary for it
|
|
||||||
*/
|
|
||||||
CodePExpr(fnd);
|
CodePExpr(fnd);
|
||||||
tmp = NewInt();
|
tmp = NewInt();
|
||||||
C_stl(tmp);
|
C_stl(tmp);
|
||||||
}
|
C_lol(tmp);
|
||||||
C_df_ilb(l1);
|
|
||||||
C_dup(int_size);
|
|
||||||
if (tmp) C_lol(tmp); else C_loc(fnd->nd_INT);
|
|
||||||
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);
|
||||||
}
|
|
||||||
else C_zlt(l2);
|
|
||||||
CodeDStore(nd);
|
CodeDStore(nd);
|
||||||
|
C_lol(tmp);
|
||||||
|
CodePExpr(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);
|
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);
|
||||||
|
CodeDStore(nd);
|
||||||
|
}
|
||||||
C_bra(l1);
|
C_bra(l1);
|
||||||
C_df_ilb(l2);
|
C_df_ilb(l2);
|
||||||
C_asp(int_size);
|
C_asp(int_size);
|
||||||
}
|
FreeInt(tmp);
|
||||||
if (tmp) 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