Fix stack growth and parameter passing

This commit is contained in:
Mid 2025-08-04 18:06:30 +03:00
parent 81b1010453
commit 012d18cdf8
5 changed files with 15 additions and 2 deletions

View File

@ -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);

View File

@ -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;
}
}

View File

@ -123,6 +123,9 @@ typedef struct {
ASTExpr;
int val;
// If true, increase this literal during stack growths
bool stackGrowth;
} ASTExprPrimitive;
typedef struct {

View File

@ -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;

View File

@ -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;