diff --git a/examples/UserListDLU.nct b/examples/UserListDLU.nct index a68fd11..e8ce170 100644 --- a/examples/UserListDLU.nct +++ b/examples/UserListDLU.nct @@ -15,6 +15,9 @@ main: u0() -> { libc.realloc = &libc_realloc; ListDLU[u32, u32; 9] list; + list.capacity = 0; + list.size = 0; + list.data = 0; ListDLU_add[u32, u32; 9](&list, &libc, 1234); ListDLU_add[u32, u32; 9](&list, &libc, 4321); ListDLU_add[u32, u32; 9](&list, &libc, 7777); diff --git a/src/ast.c b/src/ast.c index 702acd2..a7ab194 100644 --- a/src/ast.c +++ b/src/ast.c @@ -964,6 +964,7 @@ static void spill2stack_visitor(AST **aptr, AST *stmt, AST *stmtPrev, AST *chunk offset->nodeKind = AST_EXPR_PRIMITIVE; offset->type = rsp->type; offset->val = -this->stackGrowth; // This will be affected by the other part of this pass, so we must reverse + offset->stackGrowth = true; ASTExprBinaryOp *bop = calloc(1, sizeof(*bop)); bop->nodeKind = AST_EXPR_BINARY_OP; @@ -981,10 +982,10 @@ static void spill2stack_visitor(AST **aptr, AST *stmt, AST *stmtPrev, AST *chunk *aptr = (AST*) deref; } - } else if(a->nodeKind == AST_EXPR_BINARY_OP && a->exprBinOp.operands[0]->nodeKind == AST_EXPR_STACK_POINTER && a->exprBinOp.operands[1]->nodeKind == AST_EXPR_PRIMITIVE) { + } else if(a->nodeKind == AST_EXPR_PRIMITIVE && a->exprPrim.stackGrowth) { // Guaranteed to not require more dumbification - a->exprBinOp.operands[1]->exprPrim.val += this->stackGrowth; + a->exprPrim.val += this->stackGrowth; } } diff --git a/src/ast.h b/src/ast.h index 64f044d..11490c0 100644 --- a/src/ast.h +++ b/src/ast.h @@ -123,6 +123,9 @@ typedef struct { ASTExpr; int val; + + // If true, increase this literal during stack growths + bool stackGrowth; } ASTExprPrimitive; typedef struct { diff --git a/src/x86/cg.c b/src/x86/cg.c index a79712c..1225498 100644 --- a/src/x86/cg.c +++ b/src/x86/cg.c @@ -568,6 +568,7 @@ static void callee_saved_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chun offset->nodeKind = AST_EXPR_PRIMITIVE; offset->type = primitive_parse("u32"); offset->val = this->calleeOffsets[i]; + offset->stackGrowth = true; ASTExprBinaryOp *sum = calloc(1, sizeof(*sum)); sum->nodeKind = AST_EXPR_BINARY_OP; @@ -618,6 +619,7 @@ static void callee_saved_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chun offset->nodeKind = AST_EXPR_PRIMITIVE; offset->type = primitive_parse("u32"); offset->val = this->calleeOffsets[i]; + offset->stackGrowth = true; ASTExprBinaryOp *sum = calloc(1, sizeof(*sum)); sum->nodeKind = AST_EXPR_BINARY_OP; diff --git a/src/x86/dumberdowner.c b/src/x86/dumberdowner.c index ac73863..6958d39 100644 --- a/src/x86/dumberdowner.c +++ b/src/x86/dumberdowner.c @@ -221,6 +221,9 @@ static void dumben_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chu, AST * if(is_xop(call->args[i]) == XOP_NOT_XOP) { call->args[i] = xopify(tlc, chu, stmtPrev, s, call->args[i]); this->effective = 1; + + // Xopify one argument at a time otherwise stmtPrev becomes incorrect + break; } } } else if(s->stmtAssign.to && s->stmtAssign.to->nodeKind == AST_EXPR_UNARY_OP && s->stmtAssign.to->exprUnOp.operator == UNOP_NEGATE && !ast_expression_equal(s->stmtAssign.what, s->stmtAssign.to->exprUnOp.operand)) { @@ -373,6 +376,7 @@ static void pre_dumb_visitor(AST **nptr, AST *stmt, AST *stmtPrev, AST *chunk, A offset->nodeKind = AST_EXPR_PRIMITIVE; offset->type = primitive_parse("u32"); offset->val = 4 + i * 4; + offset->stackGrowth = true; ASTExprBinaryOp *sum = calloc(1, sizeof(*sum)); sum->nodeKind = AST_EXPR_BINARY_OP;