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

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